Trabajo elaborado para la asignatura “Programación y manejo de datos en la era del Big Data” de la Universitat de València durante el curso 2020-2021. La página web de la asignatura puede verse aquí: https://perezp44.github.io/intro-ds-20-21-web/. Los trabajos de mis compañeros de curso pueden verse aquí


NO ESTÁ ACABADO!

1. Introducción

En la asignatura de “Programación y manejo de datos en la era del Big Data” 1 tenemos que hacer un trabajo de tema libre, por lo que nos parecia interesante hacerlo de un tema que nos afecta a todos, como es la evolución de la pandemia de la Covid-19

Por ello, hemos buscado diferentes conjuntos de datos con los que poder hacer el análisis. Y así, mostrar de una forma más visual y sencilla diferentes cuestiones que nos pueden surgir al pensar en la Covid-19. Como por ejemplo, que incidencia de contagios ha habido dependiendo de la província o CCAA, donde se han hecho más pruebas pcr o test de ac o que paises han controlado mejor o peor la pandemía, entre otras cuestioenes.

2. Contexto mundial de la Covid-19


ORIGEN DEL COVID-19

La Covid-19 es una enfermedad infecciosa causada por un coronavirus recientemente descubierto.

Tuvo su origen en la ciudad de Wuhan, en China. Y el primer caso diagnosticado fue el 17 de noviembre de 2019. Todo y que se ha expandido rapidamente por todo el mundo.


¿QUÉ ES EL CORONAVIRUS

Los coronavirus son una serie de virus llamados así por su forma. Estos organismos no son nuevos, ya que conviven con el ser humano desde siempre. Además, hay muchos tipos de ellos, tanto en animales como en seres humanos.

Sin embargo, el análisis comparativo de esta enfermedad determinó que el SARS-CoV-2 era lo suficientemente distinto de los otros coronavirus de gravedad detectados en humanos (SARS y MERS) como para que este fuera consdierado una nueva enfermedad, recibiendo el nombre de Covid-19.


¿CÓMO SE PROPAGA EL COVID-19?

El virus que causa la Covid-19 se transmite principalmente a través de la gotículas generadas cuando una persona infectada tose, estornuda o espira. 2

Estas gotículas son demasiado pesadas para permanecer suspendidas en el aire y caen rapidamente sobre el suelo y/o las superfícies, conviertiendose estas en otra forma posible de contagio.

3. Datos utilizados para el trabajo.

Datos

Obtener los datos es fundamental para poder hacer el análisis.

Por ello, para el presente trabajo utilizaremos los datos que hemos extraido en diferentes páginas web, referenciadas al final del informe (en Referencias), y que hemos modificado para poder hacer este análisis.

De manera que, los datos modificado aparecen en la pestaña Tidy. Estos corresponden a aquellos que contienen información sobre los contagiados, recuperados y fallecidos a nivel mundial, estatal y autonómico.

Así como otras cifras, sobre las diferentes pruebas realizadas (PCR’s y Test rápidos), la saturación del sistema santiario español y algunos efectos económicos de la pandemía.

Tidy

La finalidad de este apartado es poner los código que hemos utilizado para “limpiar” los datos y a partir de los cuales hemos podido hacer gráficos, mapas, tablas…

#TIDY PARA EL "MUNDO".

library(rio)
library(tidyverse)

url_mundo <- "https://raw.githubusercontent.com/datasets/covid-19/master/data/time-series-19-covid-combined.csv"

df_mundo <- readr::read_csv(url_mundo)

df_mundo <- df_mundo %>% select(-"Province/State") %>%
            separate(Date, c("Año","Mes","Dia"), sep = "-")

df_mundo <- df_mundo  %>%
            relocate("Country/Region", .before=Año) %>%
            relocate(Año, .before=Confirmed)

df_mundo <- df_mundo %>%
            relocate(Mes, .after=Dia)

#A fecha del 01/12:

df_mundo_12 <- df_mundo %>% filter(Mes == "12" & Dia == "01")
df_mundo_12 <- df_mundo_12 %>% select(-Deaths)

#Para ver que hay países que se repiten y habrá que sumar todos los que se repiten:

df <- df_mundo_12 %>% group_by(`Country/Region`) %>% summarise(N = n())
#Países que se repiten: Australia, Canada, China, Denmark, France, Netherlands, United Kingdom.

df_b <- df_mundo_12 %>% filter(!(`Country/Region` %in% c("Australia", "Canada", "China", "Denmark", "France", "Netherlands", "United Kingdom")))


#Para Australia:
df_A <- df_mundo_12 %>% filter(`Country/Region` %in% "Australia")
df_cA <- df_A %>% mutate(Confirmed = sum(Confirmed))
df_cA <- df_cA %>% mutate(Recovered = sum(Recovered))
df_cA <- df_cA %>% slice(1)

#Para China:
df_C <- df_mundo_12 %>% filter(`Country/Region` %in% "China")
df_c <- df_C %>% mutate(Confirmed = sum(Confirmed))
df_c <- df_c %>% mutate(Recovered = sum(Recovered))
df_c <- df_c %>% slice(1)

#Para Denmark:
df_D <- df_mundo_12 %>% filter(`Country/Region` %in% "Denmark")
df_d <- df_D %>% mutate(Confirmed = sum(Confirmed))
df_d <- df_d %>% mutate(Recovered = sum(Recovered))
df_d <- df_d %>% slice(1)

#Para France:
df_F <- df_mundo_12 %>% filter(`Country/Region` %in% "France")
df_f <- df_F %>% mutate(Confirmed = sum(Confirmed))
df_f <- df_f %>% mutate(Recovered = sum(Recovered))
df_f <- df_f %>% slice(1)

#Para Netherlands:
df_N <- df_mundo_12 %>% filter(`Country/Region` %in% "Denmark")
df_n <- df_N %>% mutate(Confirmed = sum(Confirmed))
df_n <- df_n %>% mutate(Recovered = sum(Recovered))
df_n <- df_n %>% slice(1)

#Para United Kingdom:
df_U <- df_mundo_12 %>% filter(`Country/Region` %in% "Denmark")
df_u <- df_U %>% mutate(Confirmed = sum(Confirmed))
df_u <- df_u %>% mutate(Recovered = sum(Recovered))
df_u <- df_u %>% slice(1)


#Ahora tengo que juntar las tablas:
tabla <- bind_rows(df_b, df_u, df_n, df_f, df_d, df_c, df_cA)
#Gráficos de la evolución del Covid-19
library(tidyverse)
url_mundo <- "https://raw.githubusercontent.com/datasets/covid-19/master/data/time-series-19-covid-combined.csv"

df_mundo <- readr::read_csv(url_mundo)

df_mundo <- df_mundo %>% select(-"Province/State") %>%
            separate(Date, c("Año","Mes","Dia"), sep = "-")

df_mundo <- df_mundo  %>%
            relocate("Country/Region", .before=Año) %>%
            relocate(Año, .before=Confirmed)

df_mundo <- df_mundo %>%
            relocate(Mes, .after=Dia)
#Estos datos muestran el número de muertes diarias en el mundo, los hemos arreglado para poder hacer un facet_wrap con los diferentes meses y la evolución de estos según los dias. 
library(tidyverse)

#Para la tabla de muertes_dia hacemos, separamos por día y mes. Y filtrar las fechas hasta des de las primeras disponibles hasta el 31 de octubre.

library(lubridate)

muertes_dia <- rio::import(here::here("datos", "muertes_dia.xlsx"))

muertes_dia <- muertes_dia %>% mutate(Dia= day(Date)) %>% mutate(Mes= month(Date))  %>%
filter(!Mes == "11")  %>% select(!Date)

muertes_dia <- muertes_dia %>% mutate(Mes = case_when(
  Mes == 1 ~ "Enero",
  Mes == 2 ~ "Febrero",
  Mes == 3 ~ "Marzo",
  Mes == 4 ~ "Abril",
  Mes == 5 ~ "Mayo",
  Mes == 6 ~ "Junio",
  Mes == 7 ~ "Julio",
  Mes == 8 ~ "Agosto",
  Mes == 9 ~ "Septiembre",
  Mes == 10 ~ "Octubre",
))

muertes_dia$facet = factor(muertes_dia$Mes, levels = c("Enero","Febrero","Marzo", "Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre"))
#Datos_CCAA
urla <-"https://raw.githubusercontent.com/datadista/datasets/master/COVID%2019/ccaa_ingresos_camas_convencionales_uci.csv"
aaa <- rio::import(urla)

#Hay que tener en cuenta que la variable % Camas Ocupadas UCI Covid no tiene datos hasta el 21-09-2020 por lo tanto para analizar la segunda OLA si que nos sirve pero no para la primera
library(tidyverse)


datos_CCAA <- aaa %>%
  separate(Fecha, c("Año","Mes","Dia"), sep = "-") %>%
  select(-CCAA) %>% mutate(CCAA = case_when(
  cod_ine == 0 ~ "España",
  cod_ine == 1 ~ "Andalucia",
  cod_ine == 2 ~ "Aragon",
  cod_ine == 3 ~ "Asturias",
  cod_ine == 4 ~ "Islas Baleares",
  cod_ine == 5 ~ "Canarias",
  cod_ine == 6 ~ "Cantabria",
  cod_ine == 7 ~ "Castilla Leon",
  cod_ine == 8 ~ "Castilla La Mancha",
  cod_ine == 9 ~ "Cataluña",
  cod_ine == 10 ~ "Com.Valenciana",
  cod_ine == 11 ~ "Extremadura",
  cod_ine == 12 ~ "Galicia",
  cod_ine == 13 ~ "Madrid",
  cod_ine == 14 ~ "Murcia",
  cod_ine == 15 ~ "Navarra",
  cod_ine == 16 ~ "Pais Vasco",
  cod_ine == 17 ~ "La Rioja",
  cod_ine == 18 ~ "Ceuta",
  cod_ine == 19 ~ "Melilla",
)) %>% relocate(CCAA, .after=cod_ine)

datos_CCAA <- datos_CCAA %>% rename("Ingresos Ult.24h" = "Ingresos COVID últimas 24 h") %>% rename("Altas Ult24h" = "Altas COVID últimas 24 h")

4. Estudio sobre los Datos del MUNDO

4.1 Preguntas y respuestas de la situación actual.

df <- rio::import(here::here("datos", "tabla_mundo.csv"))

#Con esto podemos hacer unas tablas.

dfmax1 <- df %>% slice_max(Confirmed, n=1) #Estados Unidos es el país con más contagios.

dfmax2 <- df %>% slice_max(Recovered, n=1) #El máximo de recuperados está en India.

df_min1 <- df %>% slice_min(Confirmed, n=1) #El país con menos contagios es Vanuatu (es un país Oceania)

#https://www.europapress.es/internacional/noticia-isla-vanuatu-confirma-primer-caso-coronavirus-20201111101020.html <- Podemos poner esta notícia !!

#TABLA PARA EL PAÍS CON MENOS CONATGIOS.

Imagen <- "http://banderasmundo.es/wp-content/uploads/2017/09/vanuatu.png"

df_min1 <- df_min1 %>% add_column(Imagen)
df_min1 <- df_min1 %>% select(-c(Dia, Mes, Año))

library(gt)
Tabla_Pmencotag <- df_min1 %>% gt()

Tabla_Pmencotag <- Tabla_Pmencotag %>%
                   tab_header(title = md("**País con menos contagios de Covid-19**"),subtitle = md("A fecha: 1/12/2020"))

Tabla_Pmencotag <- Tabla_Pmencotag %>%
                tab_options(heading.background.color = "coral") %>% tab_options(heading.title.font.size = 15, heading.subtitle.font.size = 13,  column_labels.font.weight =  "bold")


Tabla_Pmencotag <- Tabla_Pmencotag  %>%
  gt::text_transform(locations = cells_body(columns = vars(Imagen)), fn = function(x) {gt::web_image(x, height = 50)}) %>%  cols_align(
    align = "center")


#TABLA PARA EL PAÍS CON MÁS CONTAGIOS:


ImagenUS <- "https://upload.wikimedia.org/wikipedia/commons/a/a4/Flag_of_the_United_States.svg"

dfmax1 <- dfmax1 %>% add_column(ImagenUS)
dfmax1 <- dfmax1 %>% select(-c(Dia, Mes, Año))

library(gt)
Tabla_Pmascotag <- dfmax1 %>% gt()

Tabla_Pmascotag <- Tabla_Pmascotag %>%
                   tab_header(title = md("**País con más contagios de Covid-19**"),subtitle = md("A fecha: 1/12/2020"))

Tabla_Pmascotag <- Tabla_Pmascotag %>%
                tab_options(heading.background.color = "coral") %>% tab_options(heading.title.font.size = 15, heading.subtitle.font.size = 13,  column_labels.font.weight =  "bold")


Tabla_Pmascotag <- Tabla_Pmascotag  %>%
  gt::text_transform(locations = cells_body(columns = vars(ImagenUS)), fn = function(x) {gt::web_image(x, height = 50)}) %>%  cols_align(
    align = "center")

#PAÍS CON MÁS RECUPERADOS DE COVID-19

ImagenI <- "https://www.banderas-mundo.es/data/flags/w580/in.png"

dfmax2 <- dfmax2 %>% add_column(ImagenI)
dfmax2 <- dfmax2 %>% select(-c(Dia, Mes, Año))


library(gt)
Tabla_Pmasrecu <- dfmax2 %>% gt()


Tabla_Pmasrecu <- Tabla_Pmasrecu %>%
                   tab_header(title = md("**País con más recuperados de Covid-19**"),subtitle = md("A fecha: 1/12/2020"))

Tabla_Pmasrecu <- Tabla_Pmasrecu %>%
                tab_options(heading.background.color = "coral") %>% tab_options(heading.title.font.size = 15, heading.subtitle.font.size = 13,  column_labels.font.weight =  "bold")


Tabla_Pmasrecu <- Tabla_Pmasrecu  %>%
  gt::text_transform(locations = cells_body(columns = vars(ImagenI)), fn = function(x) {gt::web_image(x, height = 50)}) %>%  cols_align(
    align = "center")

¿CUÁL ES EL PAÍS CON MÁS PERSONAS CONTAGIADAS?


País con más contagios de Covid-19
A fecha: 1/12/2020
Country/Region Confirmed Recovered ImagenUS
US 13721858 5226581


¿CUÁL ES EL PAÍS CON MENOS CONTAGIOS?


País con menos contagios de Covid-19
A fecha: 1/12/2020
Country/Region Confirmed Recovered Imagen
Vanuatu 1 0


¿EN QUÉ PAÍS HAY MÁS PERSONAS RECUPERADAS?


País con más recuperados de Covid-19
A fecha: 1/12/2020
Country/Region Confirmed Recovered ImagenI
India 9499413 8932647

4.2 Los 10 países con más casos de Coronavirus, ¿Cuáles son?

a <- ggplot(covid)+
  geom_col(aes(ranking,cu_cases,fill=cname))+
  scale_fill_manual(values=mycolors)+
  geom_text(aes(ranking,cu_cases,label=as.factor(cu_cases)),hjust=-0.1,size=5)+
  geom_text(aes(ranking, y=0 , label = cname), hjust=1.1,size=5) +
  geom_text(aes(x=10, y=max(cu_cases) , label = as.factor(date)), vjust = 0, hjust=1, alpha = 0.1,  col = "black", size = 20)+
  labs(title = "Evolución de los casos positivos de Covid-19 en el mundo",
       subtitle = "Datos de la Universidad Johns Hopkins",
       x=NULL,
       y=NULL)+
  coord_flip(clip = "off")+
  scale_x_reverse()+
  theme_minimal()+
  theme(legend.position = "none",
        axis.title.y = element_blank(),
        axis.title.x = element_blank(),
        axis.text.y = element_blank(),
        axis.text.x = element_blank(),
        plot.title = element_text(hjust = 0, size=20,face="bold"),
        plot.subtitle = element_text(hjust = 0, size=12, face="italic"),
        plot.margin = margin(1, 4, 1, 3, "cm"))+
  transition_states(date,transition_length = 1,state_length = 0,wrap = FALSE)
 animate(a,
        nframes = 800,
        fps = 24,
        end_pause = 200,
        width = 1000,
        height = 600,
        type = "cairo")

4.3 Evolución de los contagios (a nivel mundial)

Para poder entender como ha sido la propagación del virus a nivel mundial nos parecia interesante analizar diferentes países que no fueran parecidos entre si. Para ello elegimos estos países - Estados Unidos, Nigeria, Portugal y Japón - e hicimos un gráfico donde mostramos la evolución de los casos registrados diariamente.

#Gráfico para US:
df_mundoUS<- df_mundo %>% filter(`Country/Region` == "US") %>% select(-c(Recovered, Deaths))

df_mundoUSS <- df_mundoUS %>% summarise(dif = diff(Confirmed))

dfUS <- df_mundoUS %>% select(`Country/Region`,Dia, Mes)
dfUS <- dfUS %>% slice(-1)
US <- bind_cols(dfUS, df_mundoUSS)

US <- US %>% mutate(ranking = row_number())

graficoUS <- ggplot(US, aes(ranking, dif, color = Mes)) + geom_line() + labs(title = "EEUU",  x = NULL, y = "Nº casos al día") +  theme_bw() + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank())  +  theme(plot.title = element_text(hjust = 0.5)) +  theme(legend.position = "none")

#Ibamos ha hacerlo también de Australia, pero no lo he hecho porque el número de casos es bastante bajo y la diferencia entre un día y otro sale negativa. (Por lo que el gráfico no se ve bien)

#Mismo proceso para Nigeria, Japón y Portugal
#Por tanto, pongo el código para que no se vea. (echo=FALSE)

Cabe tener en cuenta que los colores muestran los diferentes meses, empezando en Enero y acabando en Noviembre.

A la vista del gráfico observamos que la evolución en los distintos países es muy diferente. En PORTUGAL, al principio de la pandemia se muestra un aumento en la curva, aunque es muy poco pronunciado y seguidamente los casos bajan y se mantienen en valores muy bajos durante un período de tiempo (meses) largo hasta que empieza la segunda ola donde los casos se disparan teniendo su máximo en casi 8000 casos registrados en un solo dia.

La evolución de NIGERIA, en cambio es muy diferente en este país el virus llega más tarde que los demás y la primera ola parece ser mayor que la segunda, aunque no se pueden tampoco sacar demasiadas conclusiones ya que el sistema sanitario de este país no es comparable al de los otros tres países analizados.

JAPÓN, sufre como vemos en el gráfico tres picos muy claros. `El primero, al principio de la pandémia, el siguiente unos meses más tarde y cuando parecia que podian controlar la situación los casos empezaron a aumentar progresivamente hasta llegar a máximos nunca vistos antes en la pandemia.

Por último, el caso de ESTADOS UNIDOS es diferente ya que la curva es siempre ascendente y no ofrece cambios extremadamente bruscos como la de los otros países. Su tendencia es clara, cada vez mas casos teniendo el pico máximo en las fechas más recientes


Continuamos con el análisis a nivel mundial, para ello ahora utilizaremos el paquete tidycovid19

#remotes::install_github("joachim-gassen/tidycovid19")
library(tidycovid19)

install.packages("maps")
library(lubridate)

merged <- download_merged_data(cached = TRUE, silent = TRUE)

a <- plot_covid19_stripes(
  type = "confirmed",
  countries = c("CHN" , "ESP",  "BRA", "ZAF", "UK", "USA"),
  sort_countries = "countries")

a <- a + theme_test() +  theme(legend.direction = "horizontal") + theme(legend.position = "bottom") +
  labs(title = "COVID-19 -CASOS DIARIOS", subtitle = " Muestra el cambio diario en casos confirmados (promedio de 7 días)", caption = "Datos obtenindos de Johns Hopkins University CSSE Github
  Repo: https://github.com/joachim-gassen/tidycovid19.
       Últimos datos obtenidos 09/12/2020")  
     

a <- a + theme(plot.title = element_text(hjust = 0.5)) +  theme(plot.subtitle = element_text(hjust = 0.5))  

[Ampliar Imagen]

En el gráfico anterior se contrasta lo que se ha comentado anteriormente. El país con más casos diarios actualmente es Estados Unidos, su tendencia es clara, como se ha dicho antes, no paran de aumentar los casos. Parecida a esta es la tendencia que observamos en Brasil, donde el primer caso se confirmó el 25 de febrero de 2020, en el estado de São Paulo, por parte de un brasileño que viajó a Italia con sintomas leves.

Por otra parte tenemos a España y Sud-Africa, sus gráficos si muestran las famosas olas donde los casos aumentaban paro luego se reducian. Concretamente en el caso de España se pueden ver como hacia el final, meses más recientes, vuelven a aparecer tonos mas verdosos lo que significa que los casos han disminuido, en comparación con los meses de marzo-abril.

El país restante es China donde según los datos que tenemos la Pandemia esta controlada ya que los valores son infimos para la población que tiene el gigante asiático. Además, se observa que al principio de la crisi sanitaria presentaba más casos que el resto de países analizados (en este gráfico)


mapaCD <- map_covid19(
  data = download_merged_data(cached = TRUE, silent = TRUE),
  type = "deaths",
  cumulative = FALSE,
  change_ave = 7,
  per_capita = TRUE)

library(ggplot2)
mapaCD <- mapaCD + labs(title = "COVID-19",
                        subtitle = "Muestra la variación diaria de muertes por 100.000 habitantes (promedio durante 7 dias)", caption = "Datos del día 07/12/2020,  
Datos obtenindos de Johns Hopkins University CSSE Github Repo: https://github.com/joachim-gassen/tidycovid19.") +
  theme(plot.title = element_text(hjust = 0.5)) +  
  theme(plot.subtitle = element_text(hjust = 0.5))

mapaCD +   scale_fill_viridis_c(direction = -1)

[Ampliar Imagen]

mapaCC <- map_covid19(
  data = download_merged_data(cached = TRUE, silent = TRUE),
  type = "confirmed",
  cumulative = FALSE,
  change_ave = 7,
  per_capita = TRUE)

mapaCC <- mapaCC + labs(title = "COVID-19 - CASOS CONFIRMADOS",
                        subtitle = "Muestra la variación diaria de casos confirmados por 100.000 habitantes (promedio durante 7 dias)", caption = "Datos del día 07/12/2020,  
Datos obtenindos de Johns Hopkins University CSSE Github Repo: https://github.com/joachim-gassen/tidycovid19.") +
  theme(plot.title = element_text(hjust = 0.5)) +  
  theme(plot.subtitle = element_text(hjust = 0.5))

mapaCC + scale_fill_viridis_c(direction = -1)

[Ampliar Imagen]

4.4 Evolución de los fallecidos (a nivel mundial)

library(gganimate)
library(plotly)

graficoM <- ggplot(muertes_dia , aes(Dia , Daily_Deaths,  color= Mes))  + geom_line() + 
  labs(title = "Evolución de muertes al día en el mundo por Covid",
    subtitle = "Desde el 24 de Enero hasta el 31 de Octubre", caption = "Elaboración propia con datos 
    del repositorio COVID19",
    y = "Muertes diarias", x = "Dias") +  
  theme(legend.position = "none") + scale_x_continuous(breaks = seq(1, 30, 5)) + 
  facet_wrap(~facet, nrow = 4, ncol = 3)  + transition_reveal(Dia)

5. Conclusiones sobre los “Datos del Mundo”.

Conclusiones

Mientras que ponemos los gráficos, tablas etc, podemos ir comentando los resultados que hemos obtenido.

Y aquí poner como las dos o tres ideas más importantes que hemos obtenido al hacer el estudio con los “datos del Mundo”

Live Map

En este apartado se muestra una bola del mundo dinámica. En ella se recoge el número de muertes, fallecidos y recuperados para cada país, como podemos observar.

Los datos provienen del Centro de ciencia e ingeniería de sistemas (JHU CSSE) de la Universidad Johns Hopkins.

Se actualizan cada día y se obtiene rapidamente gracias a la función live.map del paquete: covid19.analytics.


library(covid19.analytics)

library(tidyverse)

data <- covid19.data()
#> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

data <-data %>%
       select(-c(FIPS,Admin2,Combined_Key)) %>%
       relocate(Lat, .after=Case_Fatality_Ratio) %>%      relocate(Long_, .after=Lat)

6. Estudio sobre los datos de ESPAÑA

6.1 Datos de interés


¿CUÁL FUE LA EVOLUCIÓN DE LOS CONTAGIOS DURANTE LOS 6 PRIMEROS MESES?

#Tabla para poder interpretar el gráfico y consultar más datos

df_mundoE<- df_mundo %>% filter(`Country/Region` == "Spain") %>% select(-c(Recovered, Deaths))

df_mundoEE <- df_mundoE %>% summarise(dif = diff(Confirmed))
dfE <- df_mundoE %>% select(`Country/Region`,Dia, Mes)

df_mundoEsp<- df_mundo %>% filter(`Country/Region` == "Spain") %>% slice(-1)

#Hemos quitados dos de los datos mostrados, ya que distorsionan la gráfica. (Son datos no correctos que contienen valor 0)
Union <- bind_cols(df_mundoEsp, df_mundoEE)
Union <- Union %>% slice(-93)
Union <- Union %>% slice(-115)
Union <- Union %>% slice(-122)
Union <- Union %>% slice(-124)
Union <- Union %>% slice(-50)
Union <- Union %>% mutate(ranking = row_number())

Union <- Union  %>% select(Orden="ranking", Dia, Mes, `Contagios/dia` = "dif", ConfirmadosT="Confirmed", RecuperadosT="Recovered", MuertesT="Deaths")

TABLA RESUMEN

#En la siguiente tabla se muetra para España el número de contagios al día que hubo en tal fecha y el número de contagios, muertes o recuperados acumulados. Hay que poner una nota de págona diciendo que a partir de julio los fines de semana num de contagios/dia sale como 0)

library(reactable)
reactable(Union, defaultPageSize =  10,  paginationType = "jump", showPageSizeOptions =  TRUE , pageSizeOptions =  c ( 10 , 50 , 100 ),defaultColDef = colDef(
    align = "center",
    minWidth = 70,
    headerStyle = list(background = "lightgreen"),
    filterable = TRUE),  highlight = TRUE, outlined = TRUE,
    columns = list(
  `Contagios/dia` = colDef(style = function(value) {
    if (value > 0) {
      color <- "#e00000"}
      else {
      color <- "#008000"
    }
    list(color = color, fontWeight = "bold")
  })))

*Hay que tener en cuenta que a partir de julio los datos en fin de semana tienen un valor de 0, no obstante, deberían obviarse al consultar los datos en la tabla, ya que no resultan coherentes.

A partir de los datos representados en la tabla anteror, hemos hecho el siguiente gráfico, en él se muestra la evolución de los contagios de Covid en España desde enero hasta junio 3

Podemos observar, por tanto, la “curva” de la Primera OLA

#Gráfico de la evolución de los contagios en España des de enero hasta junio. He cogido estos meses, porque a partir de julio, los datos de los fines de semana son 0, por lo que el gráfico que sale no representa realmente el número de contagios.

df_mundoE<- df_mundo %>% filter(`Country/Region` == "Spain") %>% select(-c(Recovered, Deaths))

df_mundoEE <- df_mundoE %>% summarise(dif = diff(Confirmed))
dfE <- df_mundoE %>% select(`Country/Region`,Dia, Mes)

dfE <- dfE %>% slice(-1)
a <- bind_cols(dfE, df_mundoEE)
b <- a %>% filter(Mes %in% c("01", "02", "03", "04", "05", "06"))

b <- b%>% slice(-93) 
b <- b%>% slice(-115)
b <- b %>% slice(-122)
b <- b %>% slice(-124)
b <- b%>% slice(-50)
b <- b %>% mutate(ranking = row_number())

g6 <- ggplot(b, aes(ranking, dif, color = Mes)) + geom_line() + labs(title = "Evolución contagios Covid-19", subtitle = "De enero a junio (2020)", caption = "Elaboración propia", x = NULL, y = "Nº casos al día") +  theme_bw() + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank())  +  theme(plot.title = element_text(hjust = 0.5)) + theme(plot.subtitle = element_text(hjust = 0.5))

library(plotly)

Interpretación del gráfico En este se muestra la evolución de los contagios por Covid-19 en España durante los 6 primeros meses,los datos van concretamente desde el 23 de enero hasta el 30 de junio, además se observan 6 colores diferentes, correspondientes a los (6) meses. Esta representado de la siguiente manera: En el eje de las ordenadas se meustra el número de casos al día y en el de las abcisas un “ranking”, este corresponde a la fila de la tabla representada arriba, en la variable “orden”.

Ejemplo: Ranking 59, contagios al día: 3394 y mes 03. Para ver a que día corresponde este valor iriamos a la [Tabla Resumen] y vemos que corresponde con el día 22 (de marzo) Además, obtenemos otros datos como el número de confirmados totales hasta ese día, recuperados o muertes.

6.2 Saturación del sistema sanitario español

En este apartado se analizará la evolución de los pacientes ingresados por Covid durante las últimas 24 horas en los meses de septiembre-octubre y noviembre. Así como los dados de alta al día, también durante estos meses.

datos_CCAA <- datos_CCAA %>%
  relocate(Año, .after=Dia) %>%
  relocate(Mes, .after=Dia)

datos_Esp <- datos_CCAA %>%
  filter(cod_ine == 0) %>%
  relocate(cod_ine, .before=Dia)  #Datos para España.

datos_CV <- datos_CCAA %>%
  filter(cod_ine == 10) %>%
  relocate(cod_ine, .before=Dia) #Datos para la Comunitat Valenciana.

datos_Esp_S_N <- datos_Esp %>% filter (Mes == "09"| Mes == "10"| Mes == "11")

datos_CV_S_N<- datos_CV %>% filter (Mes == "09"| Mes == "10"| Mes == "11")

datos_Esp_N <- datos_Esp %>% filter(Mes == "11")

EVOLUCIÓN DE LOS PACIENTES INGRESADOS POR COVID-19

grafico_1 <- ggplot(datos_Esp_S_N , aes(Dia , `Total Pacientes COVID ingresados`, group=Mes, color= Mes))  + geom_line() + labs(title = " Evolución de pacientes ingresados por covid en España", subtitle = "Desde el 1 Septiembre hasta Noviembre 30", caption = "Datos repositorio COVID19")

grafico_a <- ggplot(datos_Esp_N, aes(Dia, `Altas Ult24h`,   fill = Mes )) +  scale_fill_brewer(palette="Spectral") + geom_bar(stat = "identity")+ 
  labs(title = "Número de pacientes dados de alta por COVID en España al día", subtitle = "Mes Noviembre", caption = "Elaboración propia a partir de datos COVID19") + theme(legend.position = "none")


grafico_ap <- grafico_a + 
  geom_text(aes(y=`Altas Ult24h`, 
    label = `Altas Ult24h`), position = position_dodge(width = 0.8), 
    size = 3.2, vjust=3, col = "Black")

#Preparamos los datos para hacer una TABLA
datos_CCAA_S_N <- datos_CCAA %>% filter (Mes == "09"| Mes == "10"| Mes == "11")

datos_CCAA_yaltas <- datos_CCAA_S_N %>% mutate(`%Altas por ingresados`  = (`Altas Ult24h`/ `Total Pacientes COVID ingresados`)* 100)

datos_CCAA_yaltas <- datos_CCAA_yaltas %>% select(Dia, Mes, CCAA, `Total Pacientes COVID ingresados`, `% Camas Ocupadas COVID`, `Total pacientes COVID en UCI`, `%Altas por ingresados`)

7. Conclusión

Referencias

Las siguientes páginas web son las que hemos utilizado para la realización del trabajo:



Para acabar este chunk incluiré mi session info:

sessioninfo::session_info() %>% details::details(summary = 'current session info') 

current session info


- Session info ---------------------------------------------------------------
 setting  value                       
 version  R version 4.0.2 (2020-06-22)
 os       Windows 10 x64              
 system   x86_64, mingw32             
 ui       RTerm                       
 language (EN)                        
 collate  Spanish_Spain.1252          
 ctype    Spanish_Spain.1252          
 tz       Europe/Paris                
 date     2020-12-10                  

- Packages -------------------------------------------------------------------
 package           * version    date       lib source                          
 ape                 5.4-1      2020-08-13 [1] CRAN (R 4.0.2)                  
 assertthat          0.2.1      2019-03-21 [1] CRAN (R 4.0.2)                  
 backports           1.2.0      2020-11-02 [1] CRAN (R 4.0.3)                  
 bitops              1.0-6      2013-08-17 [1] CRAN (R 4.0.3)                  
 blob                1.2.1      2020-01-20 [1] CRAN (R 4.0.2)                  
 broom               0.7.0      2020-07-09 [1] CRAN (R 4.0.2)                  
 Cairo             * 1.5-12.2   2020-07-07 [1] CRAN (R 4.0.3)                  
 caTools             1.18.0     2020-01-17 [1] CRAN (R 4.0.3)                  
 cellranger          1.1.0      2016-07-27 [1] CRAN (R 4.0.2)                  
 checkmate           2.0.0      2020-02-06 [1] CRAN (R 4.0.3)                  
 cli                 2.2.0      2020-11-20 [1] CRAN (R 4.0.2)                  
 clipr               0.7.1      2020-10-08 [1] CRAN (R 4.0.3)                  
 collapsibleTree     0.1.7      2018-08-22 [1] CRAN (R 4.0.3)                  
 colorspace          2.0-0      2020-11-11 [1] CRAN (R 4.0.3)                  
 commonmark          1.7        2018-12-01 [1] CRAN (R 4.0.2)                  
 covdata           * 0.5.95     2020-12-05 [1] Github (kjhealy/covdata@719f554)
 covid19.analytics * 2.0        2020-09-28 [1] CRAN (R 4.0.3)                  
 crayon              1.3.4      2017-09-16 [1] CRAN (R 4.0.2)                  
 crosstalk           1.1.0.1    2020-03-13 [1] CRAN (R 4.0.2)                  
 curl                4.3        2019-12-02 [1] CRAN (R 4.0.2)                  
 data.table          1.13.0     2020-07-24 [1] CRAN (R 4.0.2)                  
 data.tree           1.0.0      2020-08-03 [1] CRAN (R 4.0.3)                  
 DBI                 1.1.0      2019-12-15 [1] CRAN (R 4.0.2)                  
 dbplyr              1.4.4      2020-05-27 [1] CRAN (R 4.0.2)                  
 desc                1.2.0      2018-05-01 [1] CRAN (R 4.0.2)                  
 deSolve             1.28       2020-03-08 [1] CRAN (R 4.0.3)                  
 details             0.2.1      2020-01-12 [1] CRAN (R 4.0.3)                  
 digest              0.6.27     2020-10-24 [1] CRAN (R 4.0.3)                  
 dplyr             * 1.0.2      2020-08-18 [1] CRAN (R 4.0.2)                  
 DT                  0.16       2020-10-13 [1] CRAN (R 4.0.3)                  
 ellipsis            0.3.1      2020-05-15 [1] CRAN (R 4.0.2)                  
 evaluate            0.14       2019-05-28 [1] CRAN (R 4.0.2)                  
 fansi               0.4.1      2020-01-08 [1] CRAN (R 4.0.2)                  
 farver              2.0.3      2020-01-16 [1] CRAN (R 4.0.2)                  
 fastmap             1.0.1      2019-10-08 [1] CRAN (R 4.0.2)                  
 forcats           * 0.5.0      2020-03-01 [1] CRAN (R 4.0.2)                  
 foreign             0.8-80     2020-05-24 [2] CRAN (R 4.0.2)                  
 fs                  1.5.0      2020-07-31 [1] CRAN (R 4.0.3)                  
 generics            0.1.0      2020-10-31 [1] CRAN (R 4.0.3)                  
 gganimate         * 1.0.7      2020-10-15 [1] CRAN (R 4.0.3)                  
 ggplot2           * 3.3.2      2020-06-19 [1] CRAN (R 4.0.2)                  
 gifski            * 0.8.6      2018-09-28 [1] CRAN (R 4.0.3)                  
 glue                1.4.2      2020-08-27 [1] CRAN (R 4.0.2)                  
 gplots              3.1.0      2020-09-18 [1] CRAN (R 4.0.3)                  
 gt                * 0.2.2      2020-11-20 [1] Github (rstudio/gt@416ca71)     
 gtable              0.3.0      2019-03-25 [1] CRAN (R 4.0.2)                  
 gtools              3.8.2      2020-03-31 [1] CRAN (R 4.0.3)                  
 haven               2.3.1      2020-06-01 [1] CRAN (R 4.0.2)                  
 here                1.0.0      2020-11-15 [1] CRAN (R 4.0.3)                  
 hms                 0.5.3      2020-01-08 [1] CRAN (R 4.0.2)                  
 htmltools           0.5.0      2020-06-16 [1] CRAN (R 4.0.2)                  
 htmlwidgets         1.5.2      2020-10-03 [1] CRAN (R 4.0.3)                  
 httpuv              1.5.4      2020-06-06 [1] CRAN (R 4.0.2)                  
 httr                1.4.2      2020-07-20 [1] CRAN (R 4.0.2)                  
 jsonlite            1.7.1      2020-09-07 [1] CRAN (R 4.0.2)                  
 KernSmooth          2.23-17    2020-04-26 [2] CRAN (R 4.0.2)                  
 klippy            * 0.0.0.9500 2020-11-14 [1] Github (rlesur/klippy@378c247)  
 knitr             * 1.30       2020-09-22 [1] CRAN (R 4.0.3)                  
 labeling            0.4.2      2020-10-20 [1] CRAN (R 4.0.3)                  
 later               1.1.0.1    2020-06-05 [1] CRAN (R 4.0.2)                  
 lattice             0.20-41    2020-04-02 [2] CRAN (R 4.0.2)                  
 lazyeval            0.2.2      2019-03-15 [1] CRAN (R 4.0.2)                  
 lifecycle           0.2.0      2020-03-06 [1] CRAN (R 4.0.2)                  
 lubridate         * 1.7.9.2    2020-11-13 [1] CRAN (R 4.0.3)                  
 magrittr            2.0.1      2020-11-17 [1] CRAN (R 4.0.3)                  
 mime                0.9        2020-02-04 [1] CRAN (R 4.0.0)                  
 modelr              0.1.8      2020-05-19 [1] CRAN (R 4.0.2)                  
 munsell             0.5.0      2018-06-12 [1] CRAN (R 4.0.2)                  
 nlme                3.1-148    2020-05-24 [2] CRAN (R 4.0.2)                  
 openxlsx            4.2.2      2020-09-17 [1] CRAN (R 4.0.2)                  
 patchwork         * 1.1.0      2020-11-09 [1] CRAN (R 4.0.3)                  
 pheatmap            1.0.12     2019-01-04 [1] CRAN (R 4.0.3)                  
 pillar              1.4.7      2020-11-20 [1] CRAN (R 4.0.2)                  
 pkgconfig           2.0.3      2019-09-22 [1] CRAN (R 4.0.2)                  
 plotly            * 4.9.2.1    2020-04-04 [1] CRAN (R 4.0.3)                  
 plyr                1.8.6      2020-03-03 [1] CRAN (R 4.0.2)                  
 png                 0.1-7      2013-12-03 [1] CRAN (R 4.0.0)                  
 prettyunits         1.1.1      2020-01-24 [1] CRAN (R 4.0.2)                  
 progress            1.2.2      2019-05-16 [1] CRAN (R 4.0.2)                  
 promises            1.1.1      2020-06-09 [1] CRAN (R 4.0.2)                  
 purrr             * 0.3.4      2020-04-17 [1] CRAN (R 4.0.2)                  
 R6                  2.5.0      2020-10-28 [1] CRAN (R 4.0.3)                  
 RColorBrewer      * 1.1-2      2014-12-07 [1] CRAN (R 4.0.3)                  
 Rcpp                1.0.5      2020-07-06 [1] CRAN (R 4.0.2)                  
 reactable         * 0.2.3      2020-10-04 [1] CRAN (R 4.0.3)                  
 reactR              0.4.3      2020-07-12 [1] CRAN (R 4.0.3)                  
 readr             * 1.4.0      2020-10-05 [1] CRAN (R 4.0.3)                  
 readxl              1.3.1      2019-03-13 [1] CRAN (R 4.0.2)                  
 rentrez             1.2.3      2020-11-10 [1] CRAN (R 4.0.3)                  
 reprex              0.3.0      2019-05-16 [1] CRAN (R 4.0.2)                  
 rio               * 0.5.16     2018-11-26 [1] CRAN (R 4.0.3)                  
 rlang               0.4.8      2020-10-08 [1] CRAN (R 4.0.3)                  
 rmarkdown           2.5        2020-10-21 [1] CRAN (R 4.0.3)                  
 rprojroot           2.0.2      2020-11-15 [1] CRAN (R 4.0.3)                  
 rstudioapi          0.13       2020-11-12 [1] CRAN (R 4.0.3)                  
 rvest               0.3.6      2020-07-25 [1] CRAN (R 4.0.2)                  
 sass                0.2.0      2020-03-18 [1] CRAN (R 4.0.3)                  
 scales              1.1.1      2020-05-11 [1] CRAN (R 4.0.3)                  
 sessioninfo         1.1.1      2018-11-05 [1] CRAN (R 4.0.2)                  
 shiny               1.5.0      2020-06-23 [1] CRAN (R 4.0.2)                  
 shinycssloaders     1.0.0      2020-07-28 [1] CRAN (R 4.0.3)                  
 shinydashboard      0.7.1      2018-10-17 [1] CRAN (R 4.0.3)                  
 stringi             1.5.3      2020-09-09 [1] CRAN (R 4.0.2)                  
 stringr           * 1.4.0      2019-02-10 [1] CRAN (R 4.0.2)                  
 tibble            * 3.0.4      2020-10-12 [1] CRAN (R 4.0.3)                  
 tidyr             * 1.1.2      2020-08-27 [1] CRAN (R 4.0.2)                  
 tidyselect          1.1.0      2020-05-11 [1] CRAN (R 4.0.2)                  
 tidyverse         * 1.3.0      2019-11-21 [1] CRAN (R 4.0.3)                  
 tweenr              1.0.1      2018-12-14 [1] CRAN (R 4.0.2)                  
 vctrs               0.3.5      2020-11-17 [1] CRAN (R 4.0.3)                  
 viridisLite         0.3.0      2018-02-01 [1] CRAN (R 4.0.2)                  
 withr               2.3.0      2020-09-22 [1] CRAN (R 4.0.3)                  
 xfun                0.19       2020-10-30 [1] CRAN (R 4.0.3)                  
 XML                 3.99-0.5   2020-07-23 [1] CRAN (R 4.0.3)                  
 xml2                1.3.2      2020-04-23 [1] CRAN (R 4.0.2)                  
 xtable              1.8-4      2019-04-21 [1] CRAN (R 4.0.2)                  
 yaml                2.2.1      2020-02-01 [1] CRAN (R 4.0.2)                  
 zip                 2.1.1      2020-08-27 [1] CRAN (R 4.0.2)                  

[1] C:/Users/noeli/OneDrive/Documentos/R/win-library/4.0
[2] C:/Program Files/R/R-4.0.2/library



  1. Si quieres visitar la web del curso: https://perezp44.github.io/intro-ds-20-21-web/↩︎

  2. Si quieres consultar más información haz click aquí↩︎

  3. No hemos hecho la evolución hasta la fecha actual, dado que a partir de julio los datos de contagios en fines de semana muestran unos valores de 0 (Un resultado no coherente)↩︎

LS0tDQp0aXRsZTogPGNlbnRlcj48Rk9OVCBDT0xPUj0iRkY0RDAwIj5BTsOBTElTSVMgU09CUkUgTEEgQ09WSUQtMTk8L0ZPTlQ+PC9jZW50ZXI+DQphdXRob3I6ICJNaWVtYnJvcyBkZWwgZ3J1cG86IFxuXG5cbiAqKklnbmFjaW8gTW9udGF2YSoqIChtb25wZWlnQGFsdW1uaS51di5lcyksIFxuXG4gKipBbmRyZXUgRXNwYXJ6YSoqIChhbmVzaW1hckBhbHVtbmkudXYuZXMpIFxuXG4gKipOb2VsaWEgU8OhbmNoZXoqKiAobm9zYW41QGFsdW1uaS51di5lcykgXG5cbiBVbml2ZXJzaXRhdCBkZSBWYWzDqG5jaWEiDQpkYXRlOiAiIGByIGZvcm1hdChTeXMudGltZSgpLCAnJWQtJW0tJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHNlbGZfY29udGFpbmVkOiB5ZXMNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBzaG93DQogICAgdGhlbWU6IHVuaXRlZA0KICAgIGhpZ2hsaWdodDogcHlnbWVudHMNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogeWVzDQogICAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICBkZl9wcmludDoga2FibGUNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUNCi0tLQ0KDQpgYGB7ciBwYWNrYWdlcy1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQojIHJlbW90ZXM6Omluc3RhbGxfZ2l0aHViKCJybGVzdXIva2xpcHB5IikNCmxpYnJhcnkoa2xpcHB5KSANCmxpYnJhcnkoa25pdHIpDQpgYGANCg0KYGBge3IgY2h1bmstc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICAgICAgICAjcmVzdWx0cyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBjYWNoZSA9IEZBTFNFLCBjYWNoZS5wYXRoID0gIi9jYWNoZXMvIiwgY29tbWVudCA9ICIjPiIsDQogICAgICAgICAgICAgICAgICAgICAgI2ZpZy53aWR0aCA9IDcsICNmaWcuaGVpZ2h0PSA3LCAgIA0KICAgICAgICAgICAgICAgICAgICAgICNvdXQud2lkdGggPSA3LCBvdXQuaGVpZ2h0ID0gNywNCiAgICAgICAgICAgICAgICAgICAgICBjb2xsYXBzZSA9IFRSVUUsICBmaWcuc2hvdyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYXNwID0gNy85LCBvdXQud2lkdGggPSAiNjAlIiwgZmlnLmFsaWduID0gImNlbnRlciIpDQojLSBwYXJhIG1lam9yYXIgbG9zIGdyw6FmaWNvcywgYnVlbm8gZW4gcmVhbGlkYWQgcGFyYSBxdWUgc2UgdmVhbiBpZ3VhbCBlbiBkaXN0aW50b3MgU08NCiMtIGh0dHBzOi8vd3d3Lmp1bXBpbmdyaXZlcnMuY29tL2Jsb2cvci1rbml0ci1tYXJrZG93bi1wbmctcGRmLWdyYXBoaWNzLw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGRldiA9ICJwbmciLCBkZXYuYXJncyA9IGxpc3QodHlwZSA9ICJjYWlyby1wbmciKSkNCmBgYA0KDQpgYGB7ciBvcHRpb25zLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQpvcHRpb25zKHNjaXBlbiA9IDk5OSkgIy0gcGFyYSBxdWl0YXIgbGEgbm90YWNpw7NuIGNpZW50w61maWNhDQpvcHRpb25zKCJ5YW1sLmV2YWwuZXhwciIgPSBUUlVFKSAjLSBodHRwczovL2dpdGh1Yi5jb20vdmlraW5nL3IteWFtbC9pc3N1ZXMvNDcgIChsbyBwdXNlIHggZWwgcGIgY29uIGVsIHdhcm5pbmcpIEVuIHJlYWxpZGFkIGNyZW8gcXVlIG1lam9yIHNlcsOtYSBwb25lcmxvIGVuIFJQcm9maWxlDQpgYGANCg0KDQpgYGB7ciBrbGlwcHksIGVjaG8gPSBGQUxTRX0NCmtsaXBweTo6a2xpcHB5KHBvc2l0aW9uID0gYygidG9wIiwgInJpZ2h0IikpICMtIHJlbW90ZXM6Omluc3RhbGxfZ2l0aHViKCJybGVzdXIva2xpcHB5IikNCmBgYA0KDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij48ZGl2Lz4NCi0tLS0tLS0tLS0tLS0tLS0tDQoNCjxGT05UIENPTE9SPSJCbHVlIj5UcmFiYWpvICBlbGFib3JhZG8gcGFyYSBsYSBhc2lnbmF0dXJhICJQcm9ncmFtYWNpw7NuIHkgbWFuZWpvIGRlIGRhdG9zIGVuIGxhIGVyYSBkZWwgQmlnIERhdGEiIGRlIGxhIFVuaXZlcnNpdGF0IGRlIFZhbMOobmNpYSBkdXJhbnRlIGVsIGN1cnNvIDIwMjAtMjAyMS4gTGEgcMOhZ2luYSB3ZWIgZGUgbGEgYXNpZ25hdHVyYSBwdWVkZSB2ZXJzZSBhcXXDrTogPGh0dHBzOi8vcGVyZXpwNDQuZ2l0aHViLmlvL2ludHJvLWRzLTIwLTIxLXdlYi8+LiBMb3MgdHJhYmFqb3MgZGUgbWlzIGNvbXBhw7Flcm9zIGRlIGN1cnNvIHB1ZWRlbiB2ZXJzZSBbYXF1w61dKGh0dHBzOi8vcGVyZXpwNDQuZ2l0aHViLmlvL2ludHJvLWRzLTIwLTIxLXdlYi8wNy10cmFiYWpvcy5odG1sKTwvRk9OVD4NCg0KLS0tLS0tLS0tLS0tLS0tDQoqKk5PIEVTVMOBIEFDQUJBRE8hKioNCg0KIyMgMS4gSW50cm9kdWNjacOzbiANCg0KDQpFbiBsYSBhc2lnbmF0dXJhIGRlICJQcm9ncmFtYWNpw7NuIHkgbWFuZWpvIGRlIGRhdG9zIGVuIGxhIGVyYSBkZWwgQmlnIERhdGEiIFteMV0gdGVuZW1vcyBxdWUgaGFjZXIgdW4gdHJhYmFqbyBkZSB0ZW1hIGxpYnJlLCBwb3IgbG8gcXVlIG5vcyBwYXJlY2lhIGludGVyZXNhbnRlIGhhY2VybG8gZGUgdW4gdGVtYSBxdWUgbm9zIGFmZWN0YSBhIHRvZG9zLCBjb21vIGVzICoqbGEgZXZvbHVjacOzbiBkZSBsYSBwYW5kZW1pYSBkZSBsYSBDb3ZpZC0xOSoqIA0KDQpQb3IgZWxsbywgaGVtb3MgYnVzY2FkbyBkaWZlcmVudGVzIGNvbmp1bnRvcyBkZSBkYXRvcyBjb24gbG9zIHF1ZSBwb2RlciBoYWNlciBlbCBhbsOhbGlzaXMuIFkgYXPDrSwgbW9zdHJhciBkZSB1bmEgZm9ybWEgbcOhcyB2aXN1YWwgeSBzZW5jaWxsYSBkaWZlcmVudGVzIGN1ZXN0aW9uZXMgcXVlIG5vcyBwdWVkZW4gc3VyZ2lyIGFsIHBlbnNhciBlbiBsYSBDb3ZpZC0xOS4gQ29tbyBwb3IgZWplbXBsbywgcXVlIGluY2lkZW5jaWEgZGUgY29udGFnaW9zIGhhIGhhYmlkbyBkZXBlbmRpZW5kbyBkZSBsYSBwcm92w61uY2lhIG8gQ0NBQSwgZG9uZGUgc2UgaGFuIGhlY2hvIG3DoXMgcHJ1ZWJhcyBwY3IgbyB0ZXN0IGRlIGFjIG8gcXVlIHBhaXNlcyBoYW4gY29udHJvbGFkbyBtZWpvciBvIHBlb3IgbGEgcGFuZGVtw61hLCBlbnRyZSBvdHJhcyBjdWVzdGlvZW5lcy4gDQoNCiMjIDIuIENvbnRleHRvIG11bmRpYWwgZGUgbGEgQ292aWQtMTkgDQo8YnI+DQoNCiMjIyMgPEZPTlQgQ09MT1I9IkZGNEQwMCI+KipPUklHRU4gREVMIENPVklELTE5Kio8L0ZPTlQ+DQoNCkxhIENvdmlkLTE5IGVzIHVuYSBlbmZlcm1lZGFkICoqaW5mZWNjaW9zYSoqIGNhdXNhZGEgcG9yIHVuIGNvcm9uYXZpcnVzIHJlY2llbnRlbWVudGUgZGVzY3ViaWVydG8uIA0KDQpUdXZvIHN1IG9yaWdlbiBlbiBsYSBjaXVkYWQgZGUgV3VoYW4sIGVuIENoaW5hLiBZIGVsICoqcHJpbWVyIGNhc28qKiBkaWFnbm9zdGljYWRvIGZ1ZSBlbCAxNyBkZSBub3ZpZW1icmUgZGUgMjAxOS4gVG9kbyB5IHF1ZSBzZSBoYSBleHBhbmRpZG8gcmFwaWRhbWVudGUgcG9yIHRvZG8gZWwgbXVuZG8uDQoNCjxicj4NCg0KIyMjIyA8Rk9OVCBDT0xPUj0iRkY0RDAwIj4qKsK/UVXDiSBFUyBFTCBDT1JPTkFWSVJVUyoqPC9GT05UPg0KDQpMb3MgY29yb25hdmlydXMgc29uIHVuYSAqKnNlcmllIGRlIHZpcnVzKiogbGxhbWFkb3MgYXPDrSBwb3Igc3UgZm9ybWEuIEVzdG9zIG9yZ2FuaXNtb3Mgbm8gc29uIG51ZXZvcywgeWEgcXVlIGNvbnZpdmVuIGNvbiBlbCBzZXIgaHVtYW5vIGRlc2RlIHNpZW1wcmUuIEFkZW3DoXMsIGhheSBtdWNob3MgdGlwb3MgZGUgZWxsb3MsIHRhbnRvIGVuIGFuaW1hbGVzIGNvbW8gZW4gc2VyZXMgaHVtYW5vcy4NCg0KU2luIGVtYmFyZ28sIGVsIGFuw6FsaXNpcyBjb21wYXJhdGl2byBkZSBlc3RhIGVuZmVybWVkYWQgZGV0ZXJtaW7DsyBxdWUgZWwgU0FSUy1Db1YtMiBlcmEgbG8gc3VmaWNpZW50ZW1lbnRlIGRpc3RpbnRvIGRlIGxvcyBvdHJvcyBjb3JvbmF2aXJ1cyBkZSBncmF2ZWRhZCBkZXRlY3RhZG9zIGVuIGh1bWFub3MgKFNBUlMgeSBNRVJTKSBjb21vIHBhcmEgcXVlIGVzdGUgZnVlcmEgY29uc2RpZXJhZG8gdW5hIG51ZXZhIGVuZmVybWVkYWQsIHJlY2liaWVuZG8gZWwgbm9tYnJlIGRlICoqQ292aWQtMTkuKioNCg0KDQo8Y2VudGVyPjxpbWcgc3JjPSJpbWFnZW5lcy9jb3ZpZC5qcGciIHdpZHRoPSIzNTBweCIgLz48L2NlbnRlcj4NCg0KPGJyPg0KDQojIyMjIDxGT05UIENPTE9SPSJGRjREMDAiPioqwr9Dw5NNTyBTRSBQUk9QQUdBIEVMIENPVklELTE5PyoqPC9GT05UPg0KDQpFbCB2aXJ1cyBxdWUgY2F1c2EgbGEgQ292aWQtMTkgc2UgdHJhbnNtaXRlIHByaW5jaXBhbG1lbnRlIGEgdHJhdsOpcyBkZSBsYSBnb3TDrWN1bGFzIGdlbmVyYWRhcyBjdWFuZG8gdW5hIHBlcnNvbmEgaW5mZWN0YWRhICoqdG9zZSwgZXN0b3JudWRhIG8gZXNwaXJhLioqIFteMl0NCg0KRXN0YXMgZ290w61jdWxhcyBzb24gZGVtYXNpYWRvIHBlc2FkYXMgcGFyYSBwZXJtYW5lY2VyIHN1c3BlbmRpZGFzIGVuIGVsIGFpcmUgeSBjYWVuIHJhcGlkYW1lbnRlIHNvYnJlIGVsIHN1ZWxvIHkvbyBsYXMgc3VwZXJmw61jaWVzLCBjb252aWVydGllbmRvc2UgZXN0YXMgZW4gb3RyYSBmb3JtYSAgcG9zaWJsZSBkZSBjb250YWdpby4gDQoNCiMjIDMuIERhdG9zIHV0aWxpemFkb3MgcGFyYSBlbCB0cmFiYWpvLiB7LnRhYnNldH0NCg0KIyMjIDxGT05UIENPTE9SPSJGRjREMDAiPioqRGF0b3MqKjwvRk9OVD4NCg0KT2J0ZW5lciBsb3MgZGF0b3MgZXMgZnVuZGFtZW50YWwgcGFyYSBwb2RlciBoYWNlciBlbCBhbsOhbGlzaXMuDQoNClBvciBlbGxvLCBwYXJhIGVsIHByZXNlbnRlIHRyYWJham8gdXRpbGl6YXJlbW9zIGxvcyBkYXRvcyBxdWUgaGVtb3MgZXh0cmFpZG8gZW4gZGlmZXJlbnRlcyBww6FnaW5hcyB3ZWIsIHJlZmVyZW5jaWFkYXMgYWwgZmluYWwgZGVsIGluZm9ybWUgKGVuIFtSZWZlcmVuY2lhc10pLCB5IHF1ZSBoZW1vcyBtb2RpZmljYWRvIHBhcmEgcG9kZXIgaGFjZXIgZXN0ZSBhbsOhbGlzaXMuDQoNCkRlIG1hbmVyYSBxdWUsIGxvcyBkYXRvcyBtb2RpZmljYWRvIGFwYXJlY2VuIGVuIGxhIHBlc3Rhw7FhIFRpZHkuIEVzdG9zIGNvcnJlc3BvbmRlbiBhIGFxdWVsbG9zIHF1ZSBjb250aWVuZW4gaW5mb3JtYWNpw7NuIHNvYnJlIGxvcyBjb250YWdpYWRvcywgcmVjdXBlcmFkb3MgeSBmYWxsZWNpZG9zIGEgbml2ZWwgbXVuZGlhbCwgZXN0YXRhbCB5IGF1dG9uw7NtaWNvLiANCg0KQXPDrSBjb21vIG90cmFzIGNpZnJhcywgc29icmUgbGFzIGRpZmVyZW50ZXMgcHJ1ZWJhcyByZWFsaXphZGFzIChQQ1IncyB5IFRlc3QgcsOhcGlkb3MpLCBsYSBzYXR1cmFjacOzbiBkZWwgc2lzdGVtYSBzYW50aWFyaW8gZXNwYcOxb2wgeSBhbGd1bm9zIGVmZWN0b3MgZWNvbsOzbWljb3MgZGUgbGEgcGFuZGVtw61hLiANCg0KDQojIyMgPEZPTlQgQ09MT1I9IkZGNEQwMCI+KipUaWR5Kio8L0ZPTlQ+DQoNCkxhIGZpbmFsaWRhZCBkZSBlc3RlIGFwYXJ0YWRvIGVzIHBvbmVyIGxvcyBjw7NkaWdvIHF1ZSBoZW1vcyB1dGlsaXphZG8gcGFyYSAibGltcGlhciIgbG9zIGRhdG9zIHkgYSBwYXJ0aXIgZGUgbG9zIGN1YWxlcyBoZW1vcyBwb2RpZG8gaGFjZXIgZ3LDoWZpY29zLCBtYXBhcywgdGFibGFzLi4uDQoNCmBgYHtyfQ0KI1RJRFkgUEFSQSBFTCAiTVVORE8iLg0KDQpsaWJyYXJ5KHJpbykNCmxpYnJhcnkodGlkeXZlcnNlKQ0KDQp1cmxfbXVuZG8gPC0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9kYXRhc2V0cy9jb3ZpZC0xOS9tYXN0ZXIvZGF0YS90aW1lLXNlcmllcy0xOS1jb3ZpZC1jb21iaW5lZC5jc3YiDQoNCmRmX211bmRvIDwtIHJlYWRyOjpyZWFkX2Nzdih1cmxfbXVuZG8pDQoNCmRmX211bmRvIDwtIGRmX211bmRvICU+JSBzZWxlY3QoLSJQcm92aW5jZS9TdGF0ZSIpICU+JQ0KICAgICAgICAgICAgc2VwYXJhdGUoRGF0ZSwgYygiQcOxbyIsIk1lcyIsIkRpYSIpLCBzZXAgPSAiLSIpDQoNCmRmX211bmRvIDwtIGRmX211bmRvICAlPiUNCiAgICAgICAgICAgIHJlbG9jYXRlKCJDb3VudHJ5L1JlZ2lvbiIsIC5iZWZvcmU9QcOxbykgJT4lDQogICAgICAgICAgICByZWxvY2F0ZShBw7FvLCAuYmVmb3JlPUNvbmZpcm1lZCkNCg0KZGZfbXVuZG8gPC0gZGZfbXVuZG8gJT4lDQogICAgICAgICAgICByZWxvY2F0ZShNZXMsIC5hZnRlcj1EaWEpDQoNCiNBIGZlY2hhIGRlbCAwMS8xMjoNCg0KZGZfbXVuZG9fMTIgPC0gZGZfbXVuZG8gJT4lIGZpbHRlcihNZXMgPT0gIjEyIiAmIERpYSA9PSAiMDEiKQ0KZGZfbXVuZG9fMTIgPC0gZGZfbXVuZG9fMTIgJT4lIHNlbGVjdCgtRGVhdGhzKQ0KDQojUGFyYSB2ZXIgcXVlIGhheSBwYcOtc2VzIHF1ZSBzZSByZXBpdGVuIHkgaGFicsOhIHF1ZSBzdW1hciB0b2RvcyBsb3MgcXVlIHNlIHJlcGl0ZW46DQoNCmRmIDwtIGRmX211bmRvXzEyICU+JSBncm91cF9ieShgQ291bnRyeS9SZWdpb25gKSAlPiUgc3VtbWFyaXNlKE4gPSBuKCkpDQojUGHDrXNlcyBxdWUgc2UgcmVwaXRlbjogQXVzdHJhbGlhLCBDYW5hZGEsIENoaW5hLCBEZW5tYXJrLCBGcmFuY2UsIE5ldGhlcmxhbmRzLCBVbml0ZWQgS2luZ2RvbS4NCg0KZGZfYiA8LSBkZl9tdW5kb18xMiAlPiUgZmlsdGVyKCEoYENvdW50cnkvUmVnaW9uYCAlaW4lIGMoIkF1c3RyYWxpYSIsICJDYW5hZGEiLCAiQ2hpbmEiLCAiRGVubWFyayIsICJGcmFuY2UiLCAiTmV0aGVybGFuZHMiLCAiVW5pdGVkIEtpbmdkb20iKSkpDQoNCg0KI1BhcmEgQXVzdHJhbGlhOg0KZGZfQSA8LSBkZl9tdW5kb18xMiAlPiUgZmlsdGVyKGBDb3VudHJ5L1JlZ2lvbmAgJWluJSAiQXVzdHJhbGlhIikNCmRmX2NBIDwtIGRmX0EgJT4lIG11dGF0ZShDb25maXJtZWQgPSBzdW0oQ29uZmlybWVkKSkNCmRmX2NBIDwtIGRmX2NBICU+JSBtdXRhdGUoUmVjb3ZlcmVkID0gc3VtKFJlY292ZXJlZCkpDQpkZl9jQSA8LSBkZl9jQSAlPiUgc2xpY2UoMSkNCg0KI1BhcmEgQ2hpbmE6DQpkZl9DIDwtIGRmX211bmRvXzEyICU+JSBmaWx0ZXIoYENvdW50cnkvUmVnaW9uYCAlaW4lICJDaGluYSIpDQpkZl9jIDwtIGRmX0MgJT4lIG11dGF0ZShDb25maXJtZWQgPSBzdW0oQ29uZmlybWVkKSkNCmRmX2MgPC0gZGZfYyAlPiUgbXV0YXRlKFJlY292ZXJlZCA9IHN1bShSZWNvdmVyZWQpKQ0KZGZfYyA8LSBkZl9jICU+JSBzbGljZSgxKQ0KDQojUGFyYSBEZW5tYXJrOg0KZGZfRCA8LSBkZl9tdW5kb18xMiAlPiUgZmlsdGVyKGBDb3VudHJ5L1JlZ2lvbmAgJWluJSAiRGVubWFyayIpDQpkZl9kIDwtIGRmX0QgJT4lIG11dGF0ZShDb25maXJtZWQgPSBzdW0oQ29uZmlybWVkKSkNCmRmX2QgPC0gZGZfZCAlPiUgbXV0YXRlKFJlY292ZXJlZCA9IHN1bShSZWNvdmVyZWQpKQ0KZGZfZCA8LSBkZl9kICU+JSBzbGljZSgxKQ0KDQojUGFyYSBGcmFuY2U6DQpkZl9GIDwtIGRmX211bmRvXzEyICU+JSBmaWx0ZXIoYENvdW50cnkvUmVnaW9uYCAlaW4lICJGcmFuY2UiKQ0KZGZfZiA8LSBkZl9GICU+JSBtdXRhdGUoQ29uZmlybWVkID0gc3VtKENvbmZpcm1lZCkpDQpkZl9mIDwtIGRmX2YgJT4lIG11dGF0ZShSZWNvdmVyZWQgPSBzdW0oUmVjb3ZlcmVkKSkNCmRmX2YgPC0gZGZfZiAlPiUgc2xpY2UoMSkNCg0KI1BhcmEgTmV0aGVybGFuZHM6DQpkZl9OIDwtIGRmX211bmRvXzEyICU+JSBmaWx0ZXIoYENvdW50cnkvUmVnaW9uYCAlaW4lICJEZW5tYXJrIikNCmRmX24gPC0gZGZfTiAlPiUgbXV0YXRlKENvbmZpcm1lZCA9IHN1bShDb25maXJtZWQpKQ0KZGZfbiA8LSBkZl9uICU+JSBtdXRhdGUoUmVjb3ZlcmVkID0gc3VtKFJlY292ZXJlZCkpDQpkZl9uIDwtIGRmX24gJT4lIHNsaWNlKDEpDQoNCiNQYXJhIFVuaXRlZCBLaW5nZG9tOg0KZGZfVSA8LSBkZl9tdW5kb18xMiAlPiUgZmlsdGVyKGBDb3VudHJ5L1JlZ2lvbmAgJWluJSAiRGVubWFyayIpDQpkZl91IDwtIGRmX1UgJT4lIG11dGF0ZShDb25maXJtZWQgPSBzdW0oQ29uZmlybWVkKSkNCmRmX3UgPC0gZGZfdSAlPiUgbXV0YXRlKFJlY292ZXJlZCA9IHN1bShSZWNvdmVyZWQpKQ0KZGZfdSA8LSBkZl91ICU+JSBzbGljZSgxKQ0KDQoNCiNBaG9yYSB0ZW5nbyBxdWUganVudGFyIGxhcyB0YWJsYXM6DQp0YWJsYSA8LSBiaW5kX3Jvd3MoZGZfYiwgZGZfdSwgZGZfbiwgZGZfZiwgZGZfZCwgZGZfYywgZGZfY0EpDQpgYGANCg0KYGBge3J9DQojR3LDoWZpY29zIGRlIGxhIGV2b2x1Y2nDs24gZGVsIENvdmlkLTE5DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCnVybF9tdW5kbyA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2RhdGFzZXRzL2NvdmlkLTE5L21hc3Rlci9kYXRhL3RpbWUtc2VyaWVzLTE5LWNvdmlkLWNvbWJpbmVkLmNzdiINCg0KZGZfbXVuZG8gPC0gcmVhZHI6OnJlYWRfY3N2KHVybF9tdW5kbykNCg0KZGZfbXVuZG8gPC0gZGZfbXVuZG8gJT4lIHNlbGVjdCgtIlByb3ZpbmNlL1N0YXRlIikgJT4lDQogICAgICAgICAgICBzZXBhcmF0ZShEYXRlLCBjKCJBw7FvIiwiTWVzIiwiRGlhIiksIHNlcCA9ICItIikNCg0KZGZfbXVuZG8gPC0gZGZfbXVuZG8gICU+JQ0KICAgICAgICAgICAgcmVsb2NhdGUoIkNvdW50cnkvUmVnaW9uIiwgLmJlZm9yZT1Bw7FvKSAlPiUNCiAgICAgICAgICAgIHJlbG9jYXRlKEHDsW8sIC5iZWZvcmU9Q29uZmlybWVkKQ0KDQpkZl9tdW5kbyA8LSBkZl9tdW5kbyAlPiUNCiAgICAgICAgICAgIHJlbG9jYXRlKE1lcywgLmFmdGVyPURpYSkNCmBgYA0KDQpgYGB7cn0NCiNFc3RvcyBkYXRvcyBtdWVzdHJhbiBlbCBuw7ptZXJvIGRlIG11ZXJ0ZXMgZGlhcmlhcyBlbiBlbCBtdW5kbywgbG9zIGhlbW9zIGFycmVnbGFkbyBwYXJhIHBvZGVyIGhhY2VyIHVuIGZhY2V0X3dyYXAgY29uIGxvcyBkaWZlcmVudGVzIG1lc2VzIHkgbGEgZXZvbHVjacOzbiBkZSBlc3RvcyBzZWfDum4gbG9zIGRpYXMuIA0KbGlicmFyeSh0aWR5dmVyc2UpDQoNCiNQYXJhIGxhIHRhYmxhIGRlIG11ZXJ0ZXNfZGlhIGhhY2Vtb3MsIHNlcGFyYW1vcyBwb3IgZMOtYSB5IG1lcy4gWSBmaWx0cmFyIGxhcyBmZWNoYXMgaGFzdGEgZGVzIGRlIGxhcyBwcmltZXJhcyBkaXNwb25pYmxlcyBoYXN0YSBlbCAzMSBkZSBvY3R1YnJlLg0KDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCg0KbXVlcnRlc19kaWEgPC0gcmlvOjppbXBvcnQoaGVyZTo6aGVyZSgiZGF0b3MiLCAibXVlcnRlc19kaWEueGxzeCIpKQ0KDQptdWVydGVzX2RpYSA8LSBtdWVydGVzX2RpYSAlPiUgbXV0YXRlKERpYT0gZGF5KERhdGUpKSAlPiUgbXV0YXRlKE1lcz0gbW9udGgoRGF0ZSkpICAlPiUNCmZpbHRlcighTWVzID09ICIxMSIpICAlPiUgc2VsZWN0KCFEYXRlKQ0KDQptdWVydGVzX2RpYSA8LSBtdWVydGVzX2RpYSAlPiUgbXV0YXRlKE1lcyA9IGNhc2Vfd2hlbigNCiAgTWVzID09IDEgfiAiRW5lcm8iLA0KICBNZXMgPT0gMiB+ICJGZWJyZXJvIiwNCiAgTWVzID09IDMgfiAiTWFyem8iLA0KICBNZXMgPT0gNCB+ICJBYnJpbCIsDQogIE1lcyA9PSA1IH4gIk1heW8iLA0KICBNZXMgPT0gNiB+ICJKdW5pbyIsDQogIE1lcyA9PSA3IH4gIkp1bGlvIiwNCiAgTWVzID09IDggfiAiQWdvc3RvIiwNCiAgTWVzID09IDkgfiAiU2VwdGllbWJyZSIsDQogIE1lcyA9PSAxMCB+ICJPY3R1YnJlIiwNCikpDQoNCm11ZXJ0ZXNfZGlhJGZhY2V0ID0gZmFjdG9yKG11ZXJ0ZXNfZGlhJE1lcywgbGV2ZWxzID0gYygiRW5lcm8iLCJGZWJyZXJvIiwiTWFyem8iLCAiQWJyaWwiLCJNYXlvIiwiSnVuaW8iLCJKdWxpbyIsIkFnb3N0byIsIlNlcHRpZW1icmUiLCJPY3R1YnJlIikpDQpgYGANCg0KYGBge3J9DQojRGF0b3NfQ0NBQQ0KdXJsYSA8LSJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vZGF0YWRpc3RhL2RhdGFzZXRzL21hc3Rlci9DT1ZJRCUyMDE5L2NjYWFfaW5ncmVzb3NfY2FtYXNfY29udmVuY2lvbmFsZXNfdWNpLmNzdiINCmFhYSA8LSByaW86OmltcG9ydCh1cmxhKQ0KDQojSGF5IHF1ZSB0ZW5lciBlbiBjdWVudGEgcXVlIGxhIHZhcmlhYmxlICUgQ2FtYXMgT2N1cGFkYXMgVUNJIENvdmlkIG5vIHRpZW5lIGRhdG9zIGhhc3RhIGVsIDIxLTA5LTIwMjAgcG9yIGxvIHRhbnRvIHBhcmEgYW5hbGl6YXIgbGEgc2VndW5kYSBPTEEgc2kgcXVlIG5vcyBzaXJ2ZSBwZXJvIG5vIHBhcmEgbGEgcHJpbWVyYQ0KbGlicmFyeSh0aWR5dmVyc2UpDQoNCg0KZGF0b3NfQ0NBQSA8LSBhYWEgJT4lDQogIHNlcGFyYXRlKEZlY2hhLCBjKCJBw7FvIiwiTWVzIiwiRGlhIiksIHNlcCA9ICItIikgJT4lDQogIHNlbGVjdCgtQ0NBQSkgJT4lIG11dGF0ZShDQ0FBID0gY2FzZV93aGVuKA0KICBjb2RfaW5lID09IDAgfiAiRXNwYcOxYSIsDQogIGNvZF9pbmUgPT0gMSB+ICJBbmRhbHVjaWEiLA0KICBjb2RfaW5lID09IDIgfiAiQXJhZ29uIiwNCiAgY29kX2luZSA9PSAzIH4gIkFzdHVyaWFzIiwNCiAgY29kX2luZSA9PSA0IH4gIklzbGFzIEJhbGVhcmVzIiwNCiAgY29kX2luZSA9PSA1IH4gIkNhbmFyaWFzIiwNCiAgY29kX2luZSA9PSA2IH4gIkNhbnRhYnJpYSIsDQogIGNvZF9pbmUgPT0gNyB+ICJDYXN0aWxsYSBMZW9uIiwNCiAgY29kX2luZSA9PSA4IH4gIkNhc3RpbGxhIExhIE1hbmNoYSIsDQogIGNvZF9pbmUgPT0gOSB+ICJDYXRhbHXDsWEiLA0KICBjb2RfaW5lID09IDEwIH4gIkNvbS5WYWxlbmNpYW5hIiwNCiAgY29kX2luZSA9PSAxMSB+ICJFeHRyZW1hZHVyYSIsDQogIGNvZF9pbmUgPT0gMTIgfiAiR2FsaWNpYSIsDQogIGNvZF9pbmUgPT0gMTMgfiAiTWFkcmlkIiwNCiAgY29kX2luZSA9PSAxNCB+ICJNdXJjaWEiLA0KICBjb2RfaW5lID09IDE1IH4gIk5hdmFycmEiLA0KICBjb2RfaW5lID09IDE2IH4gIlBhaXMgVmFzY28iLA0KICBjb2RfaW5lID09IDE3IH4gIkxhIFJpb2phIiwNCiAgY29kX2luZSA9PSAxOCB+ICJDZXV0YSIsDQogIGNvZF9pbmUgPT0gMTkgfiAiTWVsaWxsYSIsDQopKSAlPiUgcmVsb2NhdGUoQ0NBQSwgLmFmdGVyPWNvZF9pbmUpDQoNCmRhdG9zX0NDQUEgPC0gZGF0b3NfQ0NBQSAlPiUgcmVuYW1lKCJJbmdyZXNvcyBVbHQuMjRoIiA9ICJJbmdyZXNvcyBDT1ZJRCDDg8K6bHRpbWFzIDI0IGgiKSAlPiUgcmVuYW1lKCJBbHRhcyBVbHQyNGgiID0gIkFsdGFzIENPVklEIMODwrpsdGltYXMgMjQgaCIpDQpgYGANCg0KDQojIyAgNC4gRXN0dWRpbyBzb2JyZSBsb3MgKipEYXRvcyBkZWwgTVVORE8qKg0KDQojIyMgNC4xIFByZWd1bnRhcyB5IHJlc3B1ZXN0YXMgZGUgbGEgc2l0dWFjacOzbiBhY3R1YWwuDQoNCmBgYHtyfQ0KZGYgPC0gcmlvOjppbXBvcnQoaGVyZTo6aGVyZSgiZGF0b3MiLCAidGFibGFfbXVuZG8uY3N2IikpDQoNCiNDb24gZXN0byBwb2RlbW9zIGhhY2VyIHVuYXMgdGFibGFzLg0KDQpkZm1heDEgPC0gZGYgJT4lIHNsaWNlX21heChDb25maXJtZWQsIG49MSkgI0VzdGFkb3MgVW5pZG9zIGVzIGVsIHBhw61zIGNvbiBtw6FzIGNvbnRhZ2lvcy4NCg0KZGZtYXgyIDwtIGRmICU+JSBzbGljZV9tYXgoUmVjb3ZlcmVkLCBuPTEpICNFbCBtw6F4aW1vIGRlIHJlY3VwZXJhZG9zIGVzdMOhIGVuIEluZGlhLg0KDQpkZl9taW4xIDwtIGRmICU+JSBzbGljZV9taW4oQ29uZmlybWVkLCBuPTEpICNFbCBwYcOtcyBjb24gbWVub3MgY29udGFnaW9zIGVzIFZhbnVhdHUgKGVzIHVuIHBhw61zIE9jZWFuaWEpDQoNCiNodHRwczovL3d3dy5ldXJvcGFwcmVzcy5lcy9pbnRlcm5hY2lvbmFsL25vdGljaWEtaXNsYS12YW51YXR1LWNvbmZpcm1hLXByaW1lci1jYXNvLWNvcm9uYXZpcnVzLTIwMjAxMTExMTAxMDIwLmh0bWwgPC0gUG9kZW1vcyBwb25lciBlc3RhIG5vdMOtY2lhICEhDQoNCiNUQUJMQSBQQVJBIEVMIFBBw41TIENPTiBNRU5PUyBDT05BVEdJT1MuDQoNCkltYWdlbiA8LSAiaHR0cDovL2JhbmRlcmFzbXVuZG8uZXMvd3AtY29udGVudC91cGxvYWRzLzIwMTcvMDkvdmFudWF0dS5wbmciDQoNCmRmX21pbjEgPC0gZGZfbWluMSAlPiUgYWRkX2NvbHVtbihJbWFnZW4pDQpkZl9taW4xIDwtIGRmX21pbjEgJT4lIHNlbGVjdCgtYyhEaWEsIE1lcywgQcOxbykpDQoNCmxpYnJhcnkoZ3QpDQpUYWJsYV9QbWVuY290YWcgPC0gZGZfbWluMSAlPiUgZ3QoKQ0KDQpUYWJsYV9QbWVuY290YWcgPC0gVGFibGFfUG1lbmNvdGFnICU+JQ0KICAgICAgICAgICAgICAgICAgIHRhYl9oZWFkZXIodGl0bGUgPSBtZCgiKipQYcOtcyBjb24gbWVub3MgY29udGFnaW9zIGRlIENvdmlkLTE5KioiKSxzdWJ0aXRsZSA9IG1kKCJBIGZlY2hhOiAxLzEyLzIwMjAiKSkNCg0KVGFibGFfUG1lbmNvdGFnIDwtIFRhYmxhX1BtZW5jb3RhZyAlPiUNCiAgICAgICAgICAgICAgICB0YWJfb3B0aW9ucyhoZWFkaW5nLmJhY2tncm91bmQuY29sb3IgPSAiY29yYWwiKSAlPiUgdGFiX29wdGlvbnMoaGVhZGluZy50aXRsZS5mb250LnNpemUgPSAxNSwgaGVhZGluZy5zdWJ0aXRsZS5mb250LnNpemUgPSAxMywgIGNvbHVtbl9sYWJlbHMuZm9udC53ZWlnaHQgPSAgImJvbGQiKQ0KDQoNClRhYmxhX1BtZW5jb3RhZyA8LSBUYWJsYV9QbWVuY290YWcgICU+JQ0KICBndDo6dGV4dF90cmFuc2Zvcm0obG9jYXRpb25zID0gY2VsbHNfYm9keShjb2x1bW5zID0gdmFycyhJbWFnZW4pKSwgZm4gPSBmdW5jdGlvbih4KSB7Z3Q6OndlYl9pbWFnZSh4LCBoZWlnaHQgPSA1MCl9KSAlPiUgIGNvbHNfYWxpZ24oDQogICAgYWxpZ24gPSAiY2VudGVyIikNCg0KDQojVEFCTEEgUEFSQSBFTCBQQcONUyBDT04gTcOBUyBDT05UQUdJT1M6DQoNCg0KSW1hZ2VuVVMgPC0gImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2NvbW1vbnMvYS9hNC9GbGFnX29mX3RoZV9Vbml0ZWRfU3RhdGVzLnN2ZyINCg0KZGZtYXgxIDwtIGRmbWF4MSAlPiUgYWRkX2NvbHVtbihJbWFnZW5VUykNCmRmbWF4MSA8LSBkZm1heDEgJT4lIHNlbGVjdCgtYyhEaWEsIE1lcywgQcOxbykpDQoNCmxpYnJhcnkoZ3QpDQpUYWJsYV9QbWFzY290YWcgPC0gZGZtYXgxICU+JSBndCgpDQoNClRhYmxhX1BtYXNjb3RhZyA8LSBUYWJsYV9QbWFzY290YWcgJT4lDQogICAgICAgICAgICAgICAgICAgdGFiX2hlYWRlcih0aXRsZSA9IG1kKCIqKlBhw61zIGNvbiBtw6FzIGNvbnRhZ2lvcyBkZSBDb3ZpZC0xOSoqIiksc3VidGl0bGUgPSBtZCgiQSBmZWNoYTogMS8xMi8yMDIwIikpDQoNClRhYmxhX1BtYXNjb3RhZyA8LSBUYWJsYV9QbWFzY290YWcgJT4lDQogICAgICAgICAgICAgICAgdGFiX29wdGlvbnMoaGVhZGluZy5iYWNrZ3JvdW5kLmNvbG9yID0gImNvcmFsIikgJT4lIHRhYl9vcHRpb25zKGhlYWRpbmcudGl0bGUuZm9udC5zaXplID0gMTUsIGhlYWRpbmcuc3VidGl0bGUuZm9udC5zaXplID0gMTMsICBjb2x1bW5fbGFiZWxzLmZvbnQud2VpZ2h0ID0gICJib2xkIikNCg0KDQpUYWJsYV9QbWFzY290YWcgPC0gVGFibGFfUG1hc2NvdGFnICAlPiUNCiAgZ3Q6OnRleHRfdHJhbnNmb3JtKGxvY2F0aW9ucyA9IGNlbGxzX2JvZHkoY29sdW1ucyA9IHZhcnMoSW1hZ2VuVVMpKSwgZm4gPSBmdW5jdGlvbih4KSB7Z3Q6OndlYl9pbWFnZSh4LCBoZWlnaHQgPSA1MCl9KSAlPiUgIGNvbHNfYWxpZ24oDQogICAgYWxpZ24gPSAiY2VudGVyIikNCg0KI1BBw41TIENPTiBNw4FTIFJFQ1VQRVJBRE9TIERFIENPVklELTE5DQoNCkltYWdlbkkgPC0gImh0dHBzOi8vd3d3LmJhbmRlcmFzLW11bmRvLmVzL2RhdGEvZmxhZ3MvdzU4MC9pbi5wbmciDQoNCmRmbWF4MiA8LSBkZm1heDIgJT4lIGFkZF9jb2x1bW4oSW1hZ2VuSSkNCmRmbWF4MiA8LSBkZm1heDIgJT4lIHNlbGVjdCgtYyhEaWEsIE1lcywgQcOxbykpDQoNCg0KbGlicmFyeShndCkNClRhYmxhX1BtYXNyZWN1IDwtIGRmbWF4MiAlPiUgZ3QoKQ0KDQoNClRhYmxhX1BtYXNyZWN1IDwtIFRhYmxhX1BtYXNyZWN1ICU+JQ0KICAgICAgICAgICAgICAgICAgIHRhYl9oZWFkZXIodGl0bGUgPSBtZCgiKipQYcOtcyBjb24gbcOhcyByZWN1cGVyYWRvcyBkZSBDb3ZpZC0xOSoqIiksc3VidGl0bGUgPSBtZCgiQSBmZWNoYTogMS8xMi8yMDIwIikpDQoNClRhYmxhX1BtYXNyZWN1IDwtIFRhYmxhX1BtYXNyZWN1ICU+JQ0KICAgICAgICAgICAgICAgIHRhYl9vcHRpb25zKGhlYWRpbmcuYmFja2dyb3VuZC5jb2xvciA9ICJjb3JhbCIpICU+JSB0YWJfb3B0aW9ucyhoZWFkaW5nLnRpdGxlLmZvbnQuc2l6ZSA9IDE1LCBoZWFkaW5nLnN1YnRpdGxlLmZvbnQuc2l6ZSA9IDEzLCAgY29sdW1uX2xhYmVscy5mb250LndlaWdodCA9ICAiYm9sZCIpDQoNCg0KVGFibGFfUG1hc3JlY3UgPC0gVGFibGFfUG1hc3JlY3UgICU+JQ0KICBndDo6dGV4dF90cmFuc2Zvcm0obG9jYXRpb25zID0gY2VsbHNfYm9keShjb2x1bW5zID0gdmFycyhJbWFnZW5JKSksIGZuID0gZnVuY3Rpb24oeCkge2d0Ojp3ZWJfaW1hZ2UoeCwgaGVpZ2h0ID0gNTApfSkgJT4lICBjb2xzX2FsaWduKA0KICAgIGFsaWduID0gImNlbnRlciIpDQpgYGANCg0KDQo8YnI+DQo8Y2VudGVyPjxGT05UIENPTE9SPSJCbHVlIj4qKsK/Q1XDgUwgRVMgRUwgUEHDjVMgQ09OIE3DgVMgUEVSU09OQVMgQ09OVEFHSUFEQVM/Kio8L0ZPTlQ+PC9jZW50ZXI+DQogDQo8YnI+DQpgYGB7ciBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFfQ0KVGFibGFfUG1hc2NvdGFnDQpgYGANCg0KDQo8YnI+DQo8Y2VudGVyPjxGT05UIENPTE9SPSJCbHVlIj4qKsK/Q1XDgUwgRVMgRUwgUEHDjVMgQ09OIE1FTk9TIENPTlRBR0lPUz8qKjwvRk9OVD48L2NlbnRlcj4NCg0KPGJyPg0KYGBge3IgZWNobyA9IEZBTFNFLCBldmFsID0gVFJVRX0NClRhYmxhX1BtZW5jb3RhZw0KYGBgDQoNCg0KPGJyPg0KPGNlbnRlcj48Rk9OVCBDT0xPUj0iQmx1ZSI+KirCv0VOIFFVw4kgUEHDjVMgSEFZIE3DgVMgUEVSU09OQVMgUkVDVVBFUkFEQVM/Kio8L0ZPTlQ+PC9jZW50ZXI+DQo8YnI+DQpgYGB7ciBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFfQ0KVGFibGFfUG1hc3JlY3UNCmBgYA0KDQoNCg0KDQojIyMgNC4yIExvcyAxMCBwYcOtc2VzIGNvbiBtw6FzIGNhc29zIGRlIENvcm9uYXZpcnVzLCDCv0N1w6FsZXMgc29uPw0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGV2YWw9IFRSVUV9DQojR3LDoWZpY28gY29uIGxvcyAxMCBwYcOtc2VzIHF1ZSBtw6FzIGNhc29zIGRlIGNvcm9uYXZpcnVzIHByZXNlbnRhbi4NCiNMbyBoZSBzYWNhZG8gYSBwYXJ0aXIgZGUgYXF1w606IGh0dHBzOi8vcnB1YnMuY29tL0pvbmF0aGFuUnplemFrLzY1MjYzMyAhISEhDQoNCiNyZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigia2poZWFseS9jb3ZkYXRhQG1haW4iKQ0KDQpsaWJyYXJ5KGNvdmRhdGEpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeShnZ2FuaW1hdGUpDQpsaWJyYXJ5KGdpZnNraSkNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KDQojaW5zdGFsbC5wYWNrYWdlcygiQ2Fpcm8iKQ0KbGlicmFyeShDYWlybykNCg0KY292aWQgPC0gY292bmF0ICU+JQ0KICBncm91cF9ieShkYXRlKSAlPiUNCiAgYXJyYW5nZShkYXRlLCBkZXNjKGN1X2Nhc2VzKSkgJT4lDQogIG11dGF0ZShyYW5raW5nID0gcm93X251bWJlcigpKSAlPiUNCiAgZmlsdGVyKHJhbmtpbmcgPD0gMTApDQoNCiN1bmlxdWUoY292aWQkY25hbWUpICNFc3RvIG5vcyBzaXJ2ZSBwYXJhIHZlciBsYSB2YXJpYWJsZSBxdWUgbXVlc3RyYSBlbCBub21icmUgZGUgbGFzIHJlZ2lvbmVzIGRlbCBkZiBjb3ZpZC4NCg0KI0RlIGVzdGEgbWFuZXJhIGhhIGNhbWJpYWRvIGFsZ3Vub3Mgbm9tYnJlcyBkZSBsYSBmaWxhIGNuYW1lLCB0YW1iacOpbiBzZSBwb2TDrWEgaGFiZXIgaGVjaG8gY29uIGxhIGZ1bmNpw7NuIGNhc2Vfd2hlbi4NCg0KY292aWQkY25hbWUgPC0gZ3N1YigiVGFpd2FuLCBQcm92aW5jZSBvZiBDaGluYSIsICJUYWl3YW4iLCBjb3ZpZCRjbmFtZSkNCmNvdmlkJGNuYW1lIDwtIGdzdWIoIklyYW4sIElzbGFtaWMgUmVwdWJsaWMgb2YiLCAiSXJhbiIsIGNvdmlkJGNuYW1lKQ0KY292aWQkY25hbWUgPC0gZ3N1YigiUnVzc2lhbiBGZWRlcmF0aW9uIiwgIlJ1c3NpYSIsIGNvdmlkJGNuYW1lKQ0KY292aWQkY25hbWUgPC0gZ3N1YigiS29yZWEsIFJlcHVibGljIG9mIiwgIlNvdXRoIEtvcmVhIiwgY292aWQkY25hbWUpDQpjb3ZpZCRjbmFtZSA8LSBnc3ViKCJVbml0ZWQgQXJhYiBFbWlyYXRlcyIsICJVQUUiLCBjb3ZpZCRjbmFtZSkNCg0KI2N1X2Nhc2VzIHNvbiBsb3MgY2Fzb3MgYWN1bXVsYWRvcy4NCg0KI2luc3RhbGwucGFja2FnZXMoIlJDb2xvckJyZXdlciIpDQpuYi5jb2xzIDwtIDUwDQpteWNvbG9ycyA8LSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwoMTIsICJQYWlyZWQiKSkobmIuY29scykNCmBgYA0KDQpgYGB7cn0NCmEgPC0gZ2dwbG90KGNvdmlkKSsNCiAgZ2VvbV9jb2woYWVzKHJhbmtpbmcsY3VfY2FzZXMsZmlsbD1jbmFtZSkpKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9bXljb2xvcnMpKw0KICBnZW9tX3RleHQoYWVzKHJhbmtpbmcsY3VfY2FzZXMsbGFiZWw9YXMuZmFjdG9yKGN1X2Nhc2VzKSksaGp1c3Q9LTAuMSxzaXplPTUpKw0KICBnZW9tX3RleHQoYWVzKHJhbmtpbmcsIHk9MCAsIGxhYmVsID0gY25hbWUpLCBoanVzdD0xLjEsc2l6ZT01KSArDQogIGdlb21fdGV4dChhZXMoeD0xMCwgeT1tYXgoY3VfY2FzZXMpICwgbGFiZWwgPSBhcy5mYWN0b3IoZGF0ZSkpLCB2anVzdCA9IDAsIGhqdXN0PTEsIGFscGhhID0gMC4xLCAgY29sID0gImJsYWNrIiwgc2l6ZSA9IDIwKSsNCiAgbGFicyh0aXRsZSA9ICJFdm9sdWNpw7NuIGRlIGxvcyBjYXNvcyBwb3NpdGl2b3MgZGUgQ292aWQtMTkgZW4gZWwgbXVuZG8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIGxhIFVuaXZlcnNpZGFkIEpvaG5zIEhvcGtpbnMiLA0KICAgICAgIHg9TlVMTCwNCiAgICAgICB5PU5VTEwpKw0KICBjb29yZF9mbGlwKGNsaXAgPSAib2ZmIikrDQogIHNjYWxlX3hfcmV2ZXJzZSgpKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAsIHNpemU9MjAsZmFjZT0iYm9sZCIpLA0KICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCwgc2l6ZT0xMiwgZmFjZT0iaXRhbGljIiksDQogICAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDEsIDQsIDEsIDMsICJjbSIpKSsNCiAgdHJhbnNpdGlvbl9zdGF0ZXMoZGF0ZSx0cmFuc2l0aW9uX2xlbmd0aCA9IDEsc3RhdGVfbGVuZ3RoID0gMCx3cmFwID0gRkFMU0UpDQpgYGANCg0KYGBge3Igb3V0LndpZHRoPSIxMDAlIn0NCiBhbmltYXRlKGEsDQogICAgICAgIG5mcmFtZXMgPSA4MDAsDQogICAgICAgIGZwcyA9IDI0LA0KICAgICAgICBlbmRfcGF1c2UgPSAyMDAsDQogICAgICAgIHdpZHRoID0gMTAwMCwNCiAgICAgICAgaGVpZ2h0ID0gNjAwLA0KICAgICAgICB0eXBlID0gImNhaXJvIikNCmBgYA0KDQojIyMgNC4zIEV2b2x1Y2nDs24gZGUgbG9zIGNvbnRhZ2lvcyAoYSBuaXZlbCBtdW5kaWFsKQ0KDQpQYXJhIHBvZGVyIGVudGVuZGVyIGNvbW8gaGEgc2lkbyBsYSBwcm9wYWdhY2nDs24gZGVsIHZpcnVzIGEgbml2ZWwgbXVuZGlhbCBub3MgcGFyZWNpYSBpbnRlcmVzYW50ZSBhbmFsaXphciBkaWZlcmVudGVzIHBhw61zZXMgcXVlIG5vIGZ1ZXJhbiBwYXJlY2lkb3MgZW50cmUgc2kuIFBhcmEgZWxsbyBlbGVnaW1vcyBlc3RvcyBwYcOtc2VzIC0gKipFc3RhZG9zIFVuaWRvcywgTmlnZXJpYSwgUG9ydHVnYWwgeSBKYXDDs24qKiAtIGUgaGljaW1vcyB1biBncsOhZmljbyBkb25kZSBtb3N0cmFtb3MgbGEgZXZvbHVjacOzbiBkZSBsb3MgY2Fzb3MgcmVnaXN0cmFkb3MgZGlhcmlhbWVudGUuICANCg0KYGBge3IgVVN9DQojR3LDoWZpY28gcGFyYSBVUzoNCmRmX211bmRvVVM8LSBkZl9tdW5kbyAlPiUgZmlsdGVyKGBDb3VudHJ5L1JlZ2lvbmAgPT0gIlVTIikgJT4lIHNlbGVjdCgtYyhSZWNvdmVyZWQsIERlYXRocykpDQoNCmRmX211bmRvVVNTIDwtIGRmX211bmRvVVMgJT4lIHN1bW1hcmlzZShkaWYgPSBkaWZmKENvbmZpcm1lZCkpDQoNCmRmVVMgPC0gZGZfbXVuZG9VUyAlPiUgc2VsZWN0KGBDb3VudHJ5L1JlZ2lvbmAsRGlhLCBNZXMpDQpkZlVTIDwtIGRmVVMgJT4lIHNsaWNlKC0xKQ0KVVMgPC0gYmluZF9jb2xzKGRmVVMsIGRmX211bmRvVVNTKQ0KDQpVUyA8LSBVUyAlPiUgbXV0YXRlKHJhbmtpbmcgPSByb3dfbnVtYmVyKCkpDQoNCmdyYWZpY29VUyA8LSBnZ3Bsb3QoVVMsIGFlcyhyYW5raW5nLCBkaWYsIGNvbG9yID0gTWVzKSkgKyBnZW9tX2xpbmUoKSArIGxhYnModGl0bGUgPSAiRUVVVSIsICB4ID0gTlVMTCwgeSA9ICJOwrogY2Fzb3MgYWwgZMOtYSIpICsgIHRoZW1lX2J3KCkgKyB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X2JsYW5rKCksIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCkpICArICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKyAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KDQojSWJhbW9zIGhhIGhhY2VybG8gdGFtYmnDqW4gZGUgQXVzdHJhbGlhLCBwZXJvIG5vIGxvIGhlIGhlY2hvIHBvcnF1ZSBlbCBuw7ptZXJvIGRlIGNhc29zIGVzIGJhc3RhbnRlIGJham8geSBsYSBkaWZlcmVuY2lhIGVudHJlIHVuIGTDrWEgeSBvdHJvIHNhbGUgbmVnYXRpdmEuIChQb3IgbG8gcXVlIGVsIGdyw6FmaWNvIG5vIHNlIHZlIGJpZW4pDQoNCiNNaXNtbyBwcm9jZXNvIHBhcmEgTmlnZXJpYSwgSmFww7NuIHkgUG9ydHVnYWwNCiNQb3IgdGFudG8sIHBvbmdvIGVsIGPDs2RpZ28gcGFyYSBxdWUgbm8gc2UgdmVhLiAoZWNobz1GQUxTRSkNCmBgYA0KDQoNCmBgYHtyIE5pZ2VyaWEsICBlY2hvPUZBTFNFLCBldmFsPVRSVUV9DQoNCiNQYXJhIE5pZ2VyaWE6DQoNCmRmX211bmRvTjwtIGRmX211bmRvICU+JSBmaWx0ZXIoYENvdW50cnkvUmVnaW9uYCA9PSAiTmlnZXJpYSIpICU+JSBzZWxlY3QoLWMoUmVjb3ZlcmVkLCBEZWF0aHMpKQ0KDQpkZl9tdW5kb05OIDwtIGRmX211bmRvTiAlPiUgc3VtbWFyaXNlKGRpZiA9IGRpZmYoQ29uZmlybWVkKSkNCg0KZGZOIDwtIGRmX211bmRvTiAlPiUgc2VsZWN0KGBDb3VudHJ5L1JlZ2lvbmAsRGlhLCBNZXMpDQpkZk4gPC0gZGZOICU+JSBzbGljZSgtMSkNCk4gPC0gYmluZF9jb2xzKGRmTiwgZGZfbXVuZG9OTikNCg0KTiA8LSBOICU+JSBtdXRhdGUocmFua2luZyA9IHJvd19udW1iZXIoKSkNCg0KZ3JhZmljb04gPC0gZ2dwbG90KE4sIGFlcyhyYW5raW5nLCBkaWYsIGNvbG9yID0gTWVzKSkgKyBnZW9tX2xpbmUoKSArIGxhYnModGl0bGUgPSAiTmlnZXJpYSIsIHggPSBOVUxMLCB5ID0gIk7CuiBjYXNvcyBhbCBkw61hIikgKyAgdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSkgICsgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSArICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNCmBgYA0KDQoNCg0KYGBge3IgSmFww7NuLCBlY2hvPUZBTFNFLCBldmFsPVRSVUV9DQoNCiNQYXJhIEphcMOzbg0KDQpkZl9tdW5kb0o8LSBkZl9tdW5kbyAlPiUgZmlsdGVyKGBDb3VudHJ5L1JlZ2lvbmAgPT0gIkphcGFuIikgJT4lIHNlbGVjdCgtYyhSZWNvdmVyZWQsIERlYXRocykpDQoNCmRmX211bmRvSkogPC0gZGZfbXVuZG9KICU+JSBzdW1tYXJpc2UoZGlmID0gZGlmZihDb25maXJtZWQpKQ0KDQpkZkogPC0gZGZfbXVuZG9KICU+JSBzZWxlY3QoYENvdW50cnkvUmVnaW9uYCxEaWEsIE1lcykNCmRmSiA8LSBkZkogJT4lIHNsaWNlKC0xKQ0KSiA8LSBiaW5kX2NvbHMoZGZKLCBkZl9tdW5kb0pKKQ0KDQpKIDwtIEogJT4lIG11dGF0ZShyYW5raW5nID0gcm93X251bWJlcigpKQ0KDQpncmFmaWNvSiA8LSBnZ3Bsb3QoSiwgYWVzKHJhbmtpbmcsIGRpZiwgY29sb3IgPSBNZXMpKSArIGdlb21fbGluZSgpICsgbGFicyh0aXRsZSA9ICJKYXDDs24iLCAgeCA9IE5VTEwsIHkgPSAiTsK6IGNhc29zIGFsIGTDrWEiKSArICB0aGVtZV9idygpICsgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpLCBheGlzLnRpY2tzLng9ZWxlbWVudF9ibGFuaygpKSAgKyAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KYGBgDQoNCmBgYHtyIFBvcnR1Z2FsLCBlY2hvID0gRkFMU0UsZXZhbD1UUlVFfQ0KI1BhcmEgUG9ydHVnYWwNCg0KZGZfbXVuZG9QPC0gZGZfbXVuZG8gJT4lIGZpbHRlcihgQ291bnRyeS9SZWdpb25gID09ICJQb3J0dWdhbCIpICU+JSBzZWxlY3QoLWMoUmVjb3ZlcmVkLCBEZWF0aHMpKQ0KDQpkZl9tdW5kb1BQIDwtIGRmX211bmRvUCAlPiUgc3VtbWFyaXNlKGRpZiA9IGRpZmYoQ29uZmlybWVkKSkNCg0KZGZQIDwtIGRmX211bmRvUCAlPiUgc2VsZWN0KGBDb3VudHJ5L1JlZ2lvbmAsRGlhLCBNZXMpDQpkZlAgPC0gZGZQICU+JSBzbGljZSgtMSkNClAgPC0gYmluZF9jb2xzKGRmUCwgZGZfbXVuZG9QUCkNCg0KUCA8LSBQICU+JSBtdXRhdGUocmFua2luZyA9IHJvd19udW1iZXIoKSkNCg0KZ3JhZmljb1AgPC0gZ2dwbG90KFAsIGFlcyhyYW5raW5nLCBkaWYsIGNvbG9yID0gTWVzKSkgKyBnZW9tX2xpbmUoKSArIGxhYnModGl0bGUgPSAiUG9ydHVnYWwiLCAgeCA9IE5VTEwsIHkgPSAiTsK6IGNhc29zIGFsIGTDrWEiKSArICB0aGVtZV9idygpICsgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpLCBheGlzLnRpY2tzLng9ZWxlbWVudF9ibGFuaygpKSAgKyAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpKyAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KYGBgDQoNCg0KYGBge3IgZWNobz1GQUxTRSwgZXZhbCA9IFRSVUUsICBvdXQud2lkdGg9IjkwJSIgfQ0KbGlicmFyeShwYXRjaHdvcmspDQooZ3JhZmljb1VTICsgZ3JhZmljb1ApIC8gKGdyYWZpY29KICsgZ3JhZmljb04pDQpgYGANCkNhYmUgdGVuZXIgZW4gY3VlbnRhIHF1ZSBsb3MgY29sb3JlcyBtdWVzdHJhbiBsb3MgZGlmZXJlbnRlcyBtZXNlcywgZW1wZXphbmRvIGVuIEVuZXJvIHkgYWNhYmFuZG8gZW4gTm92aWVtYnJlLg0KDQpBIGxhIHZpc3RhIGRlbCBncsOhZmljbyBvYnNlcnZhbW9zIHF1ZSBsYSBldm9sdWNpw7NuIGVuIGxvcyBkaXN0aW50b3MgcGHDrXNlcyBlcyBtdXkgZGlmZXJlbnRlLiBFbiA8Rk9OVCBDT0xPUj0iRkY0RDAwIj4qKlBPUlRVR0FMKio8L0ZPTlQ+LCBhbCAqKnByaW5jaXBpbyBkZSBsYSBwYW5kZW1pYSBzZSBtdWVzdHJhIHVuIGF1bWVudG8gZW4gbGEgY3VydmEsIGF1bnF1ZSBlcyBtdXkgcG9jbyBwcm9udW5jaWFkbyoqIHkgKipzZWd1aWRhbWVudGUgbG9zIGNhc29zIGJhamFuIHkgc2UgbWFudGllbmVuIGVuIHZhbG9yZXMgbXV5IGJham9zIGR1cmFudGUgdW4gcGVyw61vZG8gZGUgdGllbXBvIChtZXNlcykgbGFyZ28qKiBoYXN0YSBxdWUgZW1waWV6YSBsYSAqKnNlZ3VuZGEgb2xhIGRvbmRlIGxvcyBjYXNvcyBzZSBkaXNwYXJhbiB0ZW5pZW5kbyBzdSBtw6F4aW1vIGVuIGNhc2kgODAwMCBjYXNvcyByZWdpc3RyYWRvcyBlbiB1biBzb2xvIGRpYSoqLg0KDQpMYSBldm9sdWNpw7NuIGRlIDxGT05UIENPTE9SPSJGRjREMDAiPioqTklHRVJJQSoqPC9GT05UPiwgZW4gY2FtYmlvIGVzIG11eSBkaWZlcmVudGUgZW4gZXN0ZSBwYcOtcyAqKmVsIHZpcnVzIGxsZWdhIG3DoXMgdGFyZGUgcXVlIGxvcyBkZW3DoXMqKiB5IGxhICoqcHJpbWVyYSBvbGEgcGFyZWNlIHNlciBtYXlvciBxdWUgbGEgc2VndW5kYSoqLCBhdW5xdWUgbm8gc2UgcHVlZGVuIHRhbXBvY28gc2FjYXIgZGVtYXNpYWRhcyBjb25jbHVzaW9uZXMgeWEgcXVlIGVsIHNpc3RlbWEgc2FuaXRhcmlvIGRlIGVzdGUgcGHDrXMgbm8gZXMgY29tcGFyYWJsZSBhbCBkZSBsb3Mgb3Ryb3MgdHJlcyBwYcOtc2VzIGFuYWxpemFkb3MuIA0KDQo8Rk9OVCBDT0xPUj0iRkY0RDAwIj4qKkpBUMOTTioqPC9GT05UPiwgc3VmcmUgY29tbyB2ZW1vcyBlbiBlbCBncsOhZmljbyAqKnRyZXMgcGljb3MqKiBtdXkgY2xhcm9zLiBgKipFbCBwcmltZXJvLCBhbCBwcmluY2lwaW8gZGUgbGEgcGFuZMOpbWlhLCBlbCBzaWd1aWVudGUgdW5vcyBtZXNlcyBtw6FzIHRhcmRlIHkgY3VhbmRvIHBhcmVjaWEgcXVlIHBvZGlhbiBjb250cm9sYXIgbGEgc2l0dWFjacOzbiBsb3MgY2Fzb3MgZW1wZXphcm9uIGEgYXVtZW50YXIgcHJvZ3Jlc2l2YW1lbnRlKiogaGFzdGEgbGxlZ2FyIGEgbcOheGltb3MgbnVuY2EgdmlzdG9zIGFudGVzIGVuIGxhIHBhbmRlbWlhLg0KDQpQb3Igw7psdGltbywgZWwgY2FzbyBkZSA8Rk9OVCBDT0xPUj0iRkY0RDAwIj4qKkVTVEFET1MgVU5JRE9TKio8L0ZPTlQ+DQplcyBkaWZlcmVudGUgeWEgcXVlICoqbGEgY3VydmEgZXMgc2llbXByZSBhc2NlbmRlbnRlKiogeSBubyBvZnJlY2UgY2FtYmlvcyBleHRyZW1hZGFtZW50ZSBicnVzY29zIGNvbW8gbGEgZGUgbG9zIG90cm9zIHBhw61zZXMuIFN1IHRlbmRlbmNpYSBlcyBjbGFyYSwgKipjYWRhIHZleiBtYXMgY2Fzb3MgdGVuaWVuZG8gZWwgcGljbyBtw6F4aW1vIGVuIGxhcyBmZWNoYXMgbcOhcyByZWNpZW50ZXMqKg0KDQo8YnI+DQoNCiMjIyBDb250aW51YW1vcyBjb24gZWwgYW7DoWxpc2lzIGEgbml2ZWwgbXVuZGlhbCwgcGFyYSBlbGxvIGFob3JhIHV0aWxpemFyZW1vcyBlbCBwYXF1ZXRlICoqdGlkeWNvdmlkMTkqKg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZXZhbCA9IEZBTFNFfQ0KI3JlbW90ZXM6Omluc3RhbGxfZ2l0aHViKCJqb2FjaGltLWdhc3Nlbi90aWR5Y292aWQxOSIpDQpsaWJyYXJ5KHRpZHljb3ZpZDE5KQ0KDQppbnN0YWxsLnBhY2thZ2VzKCJtYXBzIikNCmxpYnJhcnkobHVicmlkYXRlKQ0KDQptZXJnZWQgPC0gZG93bmxvYWRfbWVyZ2VkX2RhdGEoY2FjaGVkID0gVFJVRSwgc2lsZW50ID0gVFJVRSkNCg0KYSA8LSBwbG90X2NvdmlkMTlfc3RyaXBlcygNCiAgdHlwZSA9ICJjb25maXJtZWQiLA0KICBjb3VudHJpZXMgPSBjKCJDSE4iICwgIkVTUCIsICAiQlJBIiwgIlpBRiIsICJVSyIsICJVU0EiKSwNCiAgc29ydF9jb3VudHJpZXMgPSAiY291bnRyaWVzIikNCg0KYSA8LSBhICsgdGhlbWVfdGVzdCgpICsgIHRoZW1lKGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsNCiAgbGFicyh0aXRsZSA9ICJDT1ZJRC0xOSAtQ0FTT1MgRElBUklPUyIsIHN1YnRpdGxlID0gIiBNdWVzdHJhIGVsIGNhbWJpbyBkaWFyaW8gZW4gY2Fzb3MgY29uZmlybWFkb3MgKHByb21lZGlvIGRlIDcgZMOtYXMpIiwgY2FwdGlvbiA9ICJEYXRvcyBvYnRlbmluZG9zIGRlIEpvaG5zIEhvcGtpbnMgVW5pdmVyc2l0eSBDU1NFIEdpdGh1Yg0KICBSZXBvOiBodHRwczovL2dpdGh1Yi5jb20vam9hY2hpbS1nYXNzZW4vdGlkeWNvdmlkMTkuDQogICAgICAgw5psdGltb3MgZGF0b3Mgb2J0ZW5pZG9zIDA5LzEyLzIwMjAiKSAgDQogICAgIA0KDQphIDwtIGEgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKyAgdGhlbWUocGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICANCg0KYGBgDQoNCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRSwgb3V0LndpZHRoPSI3MCUifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1hZ2VuZXMiLCAiYmFycmFzLnBuZyIpKQ0KYGBgDQo8YSBocmVmPSIuL2ltYWdlbmVzL2JhcnJhcy5wbmciIHRhcmdldD0iX2JsYW5rIj5bQW1wbGlhciBJbWFnZW5dPC9hPg0KDQoNCkVuIGVsIGdyw6FmaWNvIGFudGVyaW9yIHNlIGNvbnRyYXN0YSBsbyBxdWUgc2UgaGEgY29tZW50YWRvIGFudGVyaW9ybWVudGUuICoqRWwgcGHDrXMgY29uIG3DoXMgY2Fzb3MgZGlhcmlvcyBhY3R1YWxtZW50ZSBlcyBFc3RhZG9zIFVuaWRvcyoqLCBzdSB0ZW5kZW5jaWEgZXMgY2xhcmEsIGNvbW8gc2UgaGEgZGljaG8gYW50ZXMsIG5vIHBhcmFuIGRlIGF1bWVudGFyIGxvcyBjYXNvcy4gUGFyZWNpZGEgYSBlc3RhIGVzIGxhIHRlbmRlbmNpYSBxdWUgb2JzZXJ2YW1vcyBlbiBCcmFzaWwsIGRvbmRlIGVsIHByaW1lciBjYXNvIHNlIGNvbmZpcm3DsyBlbCAyNSBkZSBmZWJyZXJvIGRlIDIwMjAsIGVuIGVsIGVzdGFkbyBkZSBTw6NvIFBhdWxvLCBwb3IgcGFydGUgZGUgdW4gYnJhc2lsZcOxbyBxdWUgdmlhasOzIGEgSXRhbGlhIGNvbiBzaW50b21hcyBsZXZlcy4NCg0KUG9yIG90cmEgcGFydGUgdGVuZW1vcyBhICoqRXNwYcOxYSoqIHkgKipTdWQtQWZyaWNhKiosIHN1cyBncsOhZmljb3Mgc2kgbXVlc3RyYW4gbGFzIGZhbW9zYXMgb2xhcyBkb25kZSBsb3MgY2Fzb3MgYXVtZW50YWJhbiBwYXJvIGx1ZWdvIHNlIHJlZHVjaWFuLiBDb25jcmV0YW1lbnRlIGVuIGVsIGNhc28gZGUgRXNwYcOxYSBzZSBwdWVkZW4gdmVyIGNvbW8gaGFjaWEgZWwgZmluYWwsIG1lc2VzIG3DoXMgcmVjaWVudGVzLCAgdnVlbHZlbiBhIGFwYXJlY2VyIHRvbm9zIG1hcyB2ZXJkb3NvcyBsbyBxdWUgc2lnbmlmaWNhIHF1ZSBsb3MgY2Fzb3MgaGFuIGRpc21pbnVpZG8sIGVuIGNvbXBhcmFjacOzbiBjb24gbG9zIG1lc2VzIGRlIG1hcnpvLWFicmlsLg0KDQpFbCBwYcOtcyByZXN0YW50ZSBlcyAqKkNoaW4qKmEgZG9uZGUgc2Vnw7puIGxvcyBkYXRvcyBxdWUgdGVuZW1vcyBsYSBQYW5kZW1pYSBlc3RhIGNvbnRyb2xhZGEgeWEgcXVlIGxvcyB2YWxvcmVzIHNvbiBpbmZpbW9zIHBhcmEgbGEgcG9ibGFjacOzbiBxdWUgdGllbmUgZWwgZ2lnYW50ZSBhc2nDoXRpY28uIEFkZW3DoXMsIHNlIG9ic2VydmEgcXVlIGFsIHByaW5jaXBpbyBkZSBsYSBjcmlzaSBzYW5pdGFyaWEgcHJlc2VudGFiYSBtw6FzIGNhc29zIHF1ZSBlbCByZXN0byBkZSBwYcOtc2VzIGFuYWxpemFkb3MgKGVuIGVzdGUgZ3LDoWZpY28pDQoNCjxicj4NCg0KYGBge3IgZWNobyA9IFRSVUUsIGV2YWwgPSBGQUxTRX0NCm1hcGFDRCA8LSBtYXBfY292aWQxOSgNCiAgZGF0YSA9IGRvd25sb2FkX21lcmdlZF9kYXRhKGNhY2hlZCA9IFRSVUUsIHNpbGVudCA9IFRSVUUpLA0KICB0eXBlID0gImRlYXRocyIsDQogIGN1bXVsYXRpdmUgPSBGQUxTRSwNCiAgY2hhbmdlX2F2ZSA9IDcsDQogIHBlcl9jYXBpdGEgPSBUUlVFKQ0KDQpsaWJyYXJ5KGdncGxvdDIpDQptYXBhQ0QgPC0gbWFwYUNEICsgbGFicyh0aXRsZSA9ICJDT1ZJRC0xOSIsDQogICAgICAgICAgICAgICAgICAgICAgICBzdWJ0aXRsZSA9ICJNdWVzdHJhIGxhIHZhcmlhY2nDs24gZGlhcmlhIGRlIG11ZXJ0ZXMgcG9yIDEwMC4wMDAgaGFiaXRhbnRlcyAocHJvbWVkaW8gZHVyYW50ZSA3IGRpYXMpIiwgY2FwdGlvbiA9ICJEYXRvcyBkZWwgZMOtYSAwNy8xMi8yMDIwLCAgDQpEYXRvcyBvYnRlbmluZG9zIGRlIEpvaG5zIEhvcGtpbnMgVW5pdmVyc2l0eSBDU1NFIEdpdGh1YiBSZXBvOiBodHRwczovL2dpdGh1Yi5jb20vam9hY2hpbS1nYXNzZW4vdGlkeWNvdmlkMTkuIikgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKyAgDQogIHRoZW1lKHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQ0KDQptYXBhQ0QgKyAgIHNjYWxlX2ZpbGxfdmlyaWRpc19jKGRpcmVjdGlvbiA9IC0xKQ0KYGBgDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aD0iNzAlIn0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltYWdlbmVzIiwgIk11ZXJ0ZXNfZGlhcmlhcy5wbmciKSkNCmBgYA0KPGEgaHJlZj0iLi9pbWFnZW5lcy9NdWVydGVzX2RpYXJpYXMucG5nIiB0YXJnZXQ9Il9ibGFuayI+W0FtcGxpYXIgSW1hZ2VuXTwvYT4NCg0KDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBldmFsID0gRkFMU0V9DQptYXBhQ0MgPC0gbWFwX2NvdmlkMTkoDQogIGRhdGEgPSBkb3dubG9hZF9tZXJnZWRfZGF0YShjYWNoZWQgPSBUUlVFLCBzaWxlbnQgPSBUUlVFKSwNCiAgdHlwZSA9ICJjb25maXJtZWQiLA0KICBjdW11bGF0aXZlID0gRkFMU0UsDQogIGNoYW5nZV9hdmUgPSA3LA0KICBwZXJfY2FwaXRhID0gVFJVRSkNCg0KbWFwYUNDIDwtIG1hcGFDQyArIGxhYnModGl0bGUgPSAiQ09WSUQtMTkgLSBDQVNPUyBDT05GSVJNQURPUyIsDQogICAgICAgICAgICAgICAgICAgICAgICBzdWJ0aXRsZSA9ICJNdWVzdHJhIGxhIHZhcmlhY2nDs24gZGlhcmlhIGRlIGNhc29zIGNvbmZpcm1hZG9zIHBvciAxMDAuMDAwIGhhYml0YW50ZXMgKHByb21lZGlvIGR1cmFudGUgNyBkaWFzKSIsIGNhcHRpb24gPSAiRGF0b3MgZGVsIGTDrWEgMDcvMTIvMjAyMCwgIA0KRGF0b3Mgb2J0ZW5pbmRvcyBkZSBKb2hucyBIb3BraW5zIFVuaXZlcnNpdHkgQ1NTRSBHaXRodWIgUmVwbzogaHR0cHM6Ly9naXRodWIuY29tL2pvYWNoaW0tZ2Fzc2VuL3RpZHljb3ZpZDE5LiIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICsgIA0KICB0aGVtZShwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkNCg0KbWFwYUNDICsgc2NhbGVfZmlsbF92aXJpZGlzX2MoZGlyZWN0aW9uID0gLTEpDQpgYGANCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRSwgb3V0LndpZHRoPSI2MCUifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1hZ2VuZXMiLCAiQ2Fzb3Njb25maXJtYWRvcy5wbmciKSkNCmBgYA0KPGEgaHJlZj0iLi9pbWFnZW5lcy9DYXNvc2NvbmZpcm1hZG9zLnBuZyIgdGFyZ2V0PSJfYmxhbmsiPltBbXBsaWFyIEltYWdlbl08L2E+DQoNCiMjIyA0LjQgRXZvbHVjacOzbiBkZSBsb3MgZmFsbGVjaWRvcyAoYSBuaXZlbCBtdW5kaWFsKQ0KDQoNCmBgYHtyIGdyYWZpY29NfQ0KbGlicmFyeShnZ2FuaW1hdGUpDQpsaWJyYXJ5KHBsb3RseSkNCg0KZ3JhZmljb00gPC0gZ2dwbG90KG11ZXJ0ZXNfZGlhICwgYWVzKERpYSAsIERhaWx5X0RlYXRocywgIGNvbG9yPSBNZXMpKSAgKyBnZW9tX2xpbmUoKSArIA0KICBsYWJzKHRpdGxlID0gIkV2b2x1Y2nDs24gZGUgbXVlcnRlcyBhbCBkw61hIGVuIGVsIG11bmRvIHBvciBDb3ZpZCIsDQogICAgc3VidGl0bGUgPSAiRGVzZGUgZWwgMjQgZGUgRW5lcm8gaGFzdGEgZWwgMzEgZGUgT2N0dWJyZSIsIGNhcHRpb24gPSAiRWxhYm9yYWNpw7NuIHByb3BpYSBjb24gZGF0b3MgDQogICAgZGVsIHJlcG9zaXRvcmlvIENPVklEMTkiLA0KICAgIHkgPSAiTXVlcnRlcyBkaWFyaWFzIiwgeCA9ICJEaWFzIikgKyAgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKyBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDEsIDMwLCA1KSkgKyANCiAgZmFjZXRfd3JhcCh+ZmFjZXQsIG5yb3cgPSA0LCBuY29sID0gMykgICsgdHJhbnNpdGlvbl9yZXZlYWwoRGlhKQ0KYGBgDQoNCg0KYGBge3IgZWNobz0gRkFMU0UsIGV2YWwgPSBUUlVFLCBvdXQud2lkdGg9IjgwJSJ9DQpncmFmaWNvTQ0KYGBgDQoNCiMjICA1LiBDb25jbHVzaW9uZXMgc29icmUgbG9zICJEYXRvcyBkZWwgTXVuZG8iLiB7LnRhYnNldH0NCg0KIyMjIDxGT05UIENPTE9SPSJGRjREMDAiPioqQ29uY2x1c2lvbmVzKio8L0ZPTlQ+DQoNCk1pZW50cmFzIHF1ZSBwb25lbW9zIGxvcyBncsOhZmljb3MsIHRhYmxhcyBldGMsIHBvZGVtb3MgaXIgY29tZW50YW5kbyBsb3MgcmVzdWx0YWRvcyBxdWUgaGVtb3Mgb2J0ZW5pZG8uIA0KDQpZIGFxdcOtIHBvbmVyIGNvbW8gbGFzIGRvcyBvIHRyZXMgaWRlYXMgbcOhcyBpbXBvcnRhbnRlcyBxdWUgaGVtb3Mgb2J0ZW5pZG8gYWwgaGFjZXIgZWwgZXN0dWRpbyBjb24gbG9zICJkYXRvcyBkZWwgTXVuZG8iIA0KDQojIyMgPEZPTlQgQ09MT1I9IkZGNEQwMCI+KipMaXZlIE1hcCoqPC9GT05UPiANCg0KRW4gZXN0ZSBhcGFydGFkbyBzZSBtdWVzdHJhIHVuYSBib2xhIGRlbCBtdW5kbyBkaW7DoW1pY2EuIEVuIGVsbGEgc2UgcmVjb2dlIGVsIG7Dum1lcm8gZGUgbXVlcnRlcywgZmFsbGVjaWRvcyB5IHJlY3VwZXJhZG9zIHBhcmEgY2FkYSBwYcOtcywgY29tbyBwb2RlbW9zIG9ic2VydmFyLg0KDQpMb3MgZGF0b3MgcHJvdmllbmVuIGRlbCBDZW50cm8gZGUgY2llbmNpYSBlIGluZ2VuaWVyw61hIGRlIHNpc3RlbWFzIChKSFUgQ1NTRSkgZGUgbGEgVW5pdmVyc2lkYWQgSm9obnMgSG9wa2lucy4NCg0KU2UgYWN0dWFsaXphbiBjYWRhIGTDrWEgeSBzZSBvYnRpZW5lIHJhcGlkYW1lbnRlIGdyYWNpYXMgYSBsYSBmdW5jacOzbiAqKmxpdmUubWFwKiogZGVsIHBhcXVldGU6ICoqY292aWQxOS5hbmFseXRpY3MqKi4gDQoNCmBgYHtyfQ0KDQpsaWJyYXJ5KGNvdmlkMTkuYW5hbHl0aWNzKQ0KDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCg0KZGF0YSA8LSBjb3ZpZDE5LmRhdGEoKQ0KDQpkYXRhIDwtZGF0YSAlPiUNCiAgICAgICBzZWxlY3QoLWMoRklQUyxBZG1pbjIsQ29tYmluZWRfS2V5KSkgJT4lDQogICAgICAgcmVsb2NhdGUoTGF0LCAuYWZ0ZXI9Q2FzZV9GYXRhbGl0eV9SYXRpbykgJT4lICAgICAgcmVsb2NhdGUoTG9uZ18sIC5hZnRlcj1MYXQpDQpgYGANCg0KDQpgYGB7ciBvdXQud2lkdGg9IjEwMCUiLCBldmFsID0gVFJVRSwgZWNobz0gRkFMU0V9DQpsaXZlLm1hcChkYXRhLCB0aXRsZSA9ICJDT1JPTkFWSVJVUyBFTiBFTCBNVU5ETyIsIG5vLmxlZ2VuZCA9IFRSVUUpDQpgYGANCg0KDQoNCg0KIyMgNi4gRXN0dWRpbyBzb2JyZSBsb3MgKipkYXRvcyBkZSBFU1BBw5FBKioNCg0KIyMjIDYuMSBEYXRvcyBkZSBpbnRlcsOpcw0KDQo8YnI+DQoqKsK/Q1XDgUwgRlVFIExBIEVWT0xVQ0nDk04gREUgTE9TIENPTlRBR0lPUyBEVVJBTlRFIExPUyA2IFBSSU1FUk9TIE1FU0VTPyoqDQoNCg0KYGBge3J9DQojVGFibGEgcGFyYSBwb2RlciBpbnRlcnByZXRhciBlbCBncsOhZmljbyB5IGNvbnN1bHRhciBtw6FzIGRhdG9zDQoNCmRmX211bmRvRTwtIGRmX211bmRvICU+JSBmaWx0ZXIoYENvdW50cnkvUmVnaW9uYCA9PSAiU3BhaW4iKSAlPiUgc2VsZWN0KC1jKFJlY292ZXJlZCwgRGVhdGhzKSkNCg0KZGZfbXVuZG9FRSA8LSBkZl9tdW5kb0UgJT4lIHN1bW1hcmlzZShkaWYgPSBkaWZmKENvbmZpcm1lZCkpDQpkZkUgPC0gZGZfbXVuZG9FICU+JSBzZWxlY3QoYENvdW50cnkvUmVnaW9uYCxEaWEsIE1lcykNCg0KZGZfbXVuZG9Fc3A8LSBkZl9tdW5kbyAlPiUgZmlsdGVyKGBDb3VudHJ5L1JlZ2lvbmAgPT0gIlNwYWluIikgJT4lIHNsaWNlKC0xKQ0KDQojSGVtb3MgcXVpdGFkb3MgZG9zIGRlIGxvcyBkYXRvcyBtb3N0cmFkb3MsIHlhIHF1ZSBkaXN0b3JzaW9uYW4gbGEgZ3LDoWZpY2EuIChTb24gZGF0b3Mgbm8gY29ycmVjdG9zIHF1ZSBjb250aWVuZW4gdmFsb3IgMCkNClVuaW9uIDwtIGJpbmRfY29scyhkZl9tdW5kb0VzcCwgZGZfbXVuZG9FRSkNClVuaW9uIDwtIFVuaW9uICU+JSBzbGljZSgtOTMpDQpVbmlvbiA8LSBVbmlvbiAlPiUgc2xpY2UoLTExNSkNClVuaW9uIDwtIFVuaW9uICU+JSBzbGljZSgtMTIyKQ0KVW5pb24gPC0gVW5pb24gJT4lIHNsaWNlKC0xMjQpDQpVbmlvbiA8LSBVbmlvbiAlPiUgc2xpY2UoLTUwKQ0KVW5pb24gPC0gVW5pb24gJT4lIG11dGF0ZShyYW5raW5nID0gcm93X251bWJlcigpKQ0KDQpVbmlvbiA8LSBVbmlvbiAgJT4lIHNlbGVjdChPcmRlbj0icmFua2luZyIsIERpYSwgTWVzLCBgQ29udGFnaW9zL2RpYWAgPSAiZGlmIiwgQ29uZmlybWFkb3NUPSJDb25maXJtZWQiLCBSZWN1cGVyYWRvc1Q9IlJlY292ZXJlZCIsIE11ZXJ0ZXNUPSJEZWF0aHMiKQ0KYGBgDQoNCg0KICoqVEFCTEEgUkVTVU1FTioqDQpgYGB7cn0NCiNFbiBsYSBzaWd1aWVudGUgdGFibGEgc2UgbXVldHJhIHBhcmEgRXNwYcOxYSBlbCBuw7ptZXJvIGRlIGNvbnRhZ2lvcyBhbCBkw61hIHF1ZSBodWJvIGVuIHRhbCBmZWNoYSB5IGVsIG7Dum1lcm8gZGUgY29udGFnaW9zLCBtdWVydGVzIG8gcmVjdXBlcmFkb3MgYWN1bXVsYWRvcy4gSGF5IHF1ZSBwb25lciB1bmEgbm90YSBkZSBww6Fnb25hIGRpY2llbmRvIHF1ZSBhIHBhcnRpciBkZSBqdWxpbyBsb3MgZmluZXMgZGUgc2VtYW5hIG51bSBkZSBjb250YWdpb3MvZGlhIHNhbGUgY29tbyAwKQ0KDQpsaWJyYXJ5KHJlYWN0YWJsZSkNCnJlYWN0YWJsZShVbmlvbiwgZGVmYXVsdFBhZ2VTaXplID0gIDEwLCAgcGFnaW5hdGlvblR5cGUgPSAianVtcCIsIHNob3dQYWdlU2l6ZU9wdGlvbnMgPSAgVFJVRSAsIHBhZ2VTaXplT3B0aW9ucyA9ICBjICggMTAgLCA1MCAsIDEwMCApLGRlZmF1bHRDb2xEZWYgPSBjb2xEZWYoDQogICAgYWxpZ24gPSAiY2VudGVyIiwNCiAgICBtaW5XaWR0aCA9IDcwLA0KICAgIGhlYWRlclN0eWxlID0gbGlzdChiYWNrZ3JvdW5kID0gImxpZ2h0Z3JlZW4iKSwNCiAgICBmaWx0ZXJhYmxlID0gVFJVRSksICBoaWdobGlnaHQgPSBUUlVFLCBvdXRsaW5lZCA9IFRSVUUsDQogICAgY29sdW1ucyA9IGxpc3QoDQogIGBDb250YWdpb3MvZGlhYCA9IGNvbERlZihzdHlsZSA9IGZ1bmN0aW9uKHZhbHVlKSB7DQogICAgaWYgKHZhbHVlID4gMCkgew0KICAgICAgY29sb3IgPC0gIiNlMDAwMDAifQ0KICAgICAgZWxzZSB7DQogICAgICBjb2xvciA8LSAiIzAwODAwMCINCiAgICB9DQogICAgbGlzdChjb2xvciA9IGNvbG9yLCBmb250V2VpZ2h0ID0gImJvbGQiKQ0KICB9KSkpDQpgYGANCipIYXkgcXVlIHRlbmVyIGVuIGN1ZW50YSBxdWUgYSBwYXJ0aXIgZGUganVsaW8gbG9zIGRhdG9zIGVuIGZpbiBkZSBzZW1hbmEgdGllbmVuIHVuIHZhbG9yIGRlIDAsIG5vIG9ic3RhbnRlLCBkZWJlcsOtYW4gb2J2aWFyc2UgYWwgY29uc3VsdGFyIGxvcyBkYXRvcyBlbiBsYSB0YWJsYSwgeWEgcXVlIG5vIHJlc3VsdGFuIGNvaGVyZW50ZXMuICANCg0KQSBwYXJ0aXIgZGUgbG9zIGRhdG9zIHJlcHJlc2VudGFkb3MgZW4gbGEgdGFibGEgYW50ZXJvciwgaGVtb3MgaGVjaG8gZWwgc2lndWllbnRlIGdyw6FmaWNvLCBlbiDDqWwgc2UgbXVlc3RyYSBsYSBldm9sdWNpw7NuIGRlIGxvcyBjb250YWdpb3MgZGUgQ292aWQgZW4gRXNwYcOxYSBkZXNkZSBlbmVybyBoYXN0YSBqdW5pbyBbXjNdDQoNClBvZGVtb3Mgb2JzZXJ2YXIsIHBvciB0YW50bywgIGxhICJjdXJ2YSIgZGUgbGEgPEZPTlQgQ09MT1I9IkZGNEQwMCI+KipQcmltZXJhIE9MQSoqPC9GT05UPg0KDQpgYGB7cn0NCiNHcsOhZmljbyBkZSBsYSBldm9sdWNpw7NuIGRlIGxvcyBjb250YWdpb3MgZW4gRXNwYcOxYSBkZXMgZGUgZW5lcm8gaGFzdGEganVuaW8uIEhlIGNvZ2lkbyBlc3RvcyBtZXNlcywgcG9ycXVlIGEgcGFydGlyIGRlIGp1bGlvLCBsb3MgZGF0b3MgZGUgbG9zIGZpbmVzIGRlIHNlbWFuYSBzb24gMCwgcG9yIGxvIHF1ZSBlbCBncsOhZmljbyBxdWUgc2FsZSBubyByZXByZXNlbnRhIHJlYWxtZW50ZSBlbCBuw7ptZXJvIGRlIGNvbnRhZ2lvcy4NCg0KZGZfbXVuZG9FPC0gZGZfbXVuZG8gJT4lIGZpbHRlcihgQ291bnRyeS9SZWdpb25gID09ICJTcGFpbiIpICU+JSBzZWxlY3QoLWMoUmVjb3ZlcmVkLCBEZWF0aHMpKQ0KDQpkZl9tdW5kb0VFIDwtIGRmX211bmRvRSAlPiUgc3VtbWFyaXNlKGRpZiA9IGRpZmYoQ29uZmlybWVkKSkNCmRmRSA8LSBkZl9tdW5kb0UgJT4lIHNlbGVjdChgQ291bnRyeS9SZWdpb25gLERpYSwgTWVzKQ0KDQpkZkUgPC0gZGZFICU+JSBzbGljZSgtMSkNCmEgPC0gYmluZF9jb2xzKGRmRSwgZGZfbXVuZG9FRSkNCmIgPC0gYSAlPiUgZmlsdGVyKE1lcyAlaW4lIGMoIjAxIiwgIjAyIiwgIjAzIiwgIjA0IiwgIjA1IiwgIjA2IikpDQoNCmIgPC0gYiU+JSBzbGljZSgtOTMpIA0KYiA8LSBiJT4lIHNsaWNlKC0xMTUpDQpiIDwtIGIgJT4lIHNsaWNlKC0xMjIpDQpiIDwtIGIgJT4lIHNsaWNlKC0xMjQpDQpiIDwtIGIlPiUgc2xpY2UoLTUwKQ0KYiA8LSBiICU+JSBtdXRhdGUocmFua2luZyA9IHJvd19udW1iZXIoKSkNCg0KZzYgPC0gZ2dwbG90KGIsIGFlcyhyYW5raW5nLCBkaWYsIGNvbG9yID0gTWVzKSkgKyBnZW9tX2xpbmUoKSArIGxhYnModGl0bGUgPSAiRXZvbHVjacOzbiBjb250YWdpb3MgQ292aWQtMTkiLCBzdWJ0aXRsZSA9ICJEZSBlbmVybyBhIGp1bmlvICgyMDIwKSIsIGNhcHRpb24gPSAiRWxhYm9yYWNpw7NuIHByb3BpYSIsIHggPSBOVUxMLCB5ID0gIk7CuiBjYXNvcyBhbCBkw61hIikgKyAgdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSkgICsgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSArIHRoZW1lKHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQ0KDQpsaWJyYXJ5KHBsb3RseSkNCmBgYA0KDQoNCmBgYHtyIG91dC53aWR0aD0iMTAwJSIsIG91dC5oZWlnaHQ9IjUwJSIsIGVjaG89RkFMU0UsIGV2YWw9VFJVRX0NCmdncGxvdGx5KGc2KQ0KYGBgDQoNCjxzdHlsZT4NCmRpdi5ibHVlIHsgYmFja2dyb3VuZC1jb2xvcjojYjFmZmEzOyBib3JkZXItcmFkaXVzOiA1cHg7IHBhZGRpbmc6IDIwcHg7fQ0KPC9zdHlsZT4NCjxkaXYgY2xhc3MgPSAiYmx1ZSI+DQoNCioqSW50ZXJwcmV0YWNpw7NuIGRlbCBncsOhZmljbyoqDQpFbiBlc3RlIHNlIG11ZXN0cmEgbGEgZXZvbHVjacOzbiBkZSBsb3MgY29udGFnaW9zIHBvciBDb3ZpZC0xOSBlbiBFc3Bhw7FhIGR1cmFudGUgbG9zIDYgcHJpbWVyb3MgbWVzZXMsbG9zIGRhdG9zIHZhbiBjb25jcmV0YW1lbnRlIGRlc2RlIGVsIDIzIGRlIGVuZXJvIGhhc3RhIGVsIDMwIGRlIGp1bmlvLCAgYWRlbcOhcyBzZSBvYnNlcnZhbiA2IGNvbG9yZXMgZGlmZXJlbnRlcywgY29ycmVzcG9uZGllbnRlcyBhIGxvcyAoNikgbWVzZXMuIA0KRXN0YSByZXByZXNlbnRhZG8gZGUgbGEgc2lndWllbnRlIG1hbmVyYTogRW4gZWwgZWplIGRlIGxhcyBvcmRlbmFkYXMgc2UgbWV1c3RyYSBlbCBuw7ptZXJvIGRlIGNhc29zIGFsIGTDrWEgeSBlbiBlbCBkZSBsYXMgYWJjaXNhcyB1biAicmFua2luZyIsIGVzdGUgY29ycmVzcG9uZGUgYSBsYSBmaWxhIGRlIGxhIHRhYmxhIHJlcHJlc2VudGFkYSBhcnJpYmEsIGVuIGxhIHZhcmlhYmxlICJvcmRlbiIuDQoNCioqRWplbXBsbyoqOiBfX1JhbmtpbmcgNTksIGNvbnRhZ2lvcyBhbCBkw61hOiAzMzk0IHkgbWVzIDAzLl9fIFBhcmEgdmVyIGEgcXVlIGTDrWEgY29ycmVzcG9uZGUgZXN0ZSB2YWxvciBpcmlhbW9zIGEgbGEgW1RhYmxhIFJlc3VtZW5dIHkgdmVtb3MgcXVlIGNvcnJlc3BvbmRlIGNvbiBlbCBkw61hIDIyIChkZSBtYXJ6bykgQWRlbcOhcywgb2J0ZW5lbW9zIG90cm9zIGRhdG9zIGNvbW8gZWwgbsO6bWVybyBkZSBjb25maXJtYWRvcyB0b3RhbGVzIGhhc3RhIGVzZSBkw61hLCByZWN1cGVyYWRvcyBvIG11ZXJ0ZXMuDQoNCjwvZGl2Pg0KDQojIyMgNi4yIFNhdHVyYWNpw7NuIGRlbCBzaXN0ZW1hIHNhbml0YXJpbyBlc3Bhw7FvbA0KDQpFbiBlc3RlIGFwYXJ0YWRvIHNlIGFuYWxpemFyw6EgbGEgKipldm9sdWNpw7NuKiogZGUgbG9zICoqcGFjaWVudGVzICBpbmdyZXNhZG9zIHBvciBDb3ZpZCBkdXJhbnRlIGxhcyDDumx0aW1hcyAyNCBob3JhcyBlbiBsb3MgbWVzZXMgZGUgc2VwdGllbWJyZS1vY3R1YnJlIHkgbm92aWVtYnJlKiouIEFzw60gY29tbyBsb3MgZGFkb3MgZGUgYWx0YSBhbCBkw61hLCB0YW1iacOpbiBkdXJhbnRlIGVzdG9zIG1lc2VzLg0KDQpgYGB7cn0NCmRhdG9zX0NDQUEgPC0gZGF0b3NfQ0NBQSAlPiUNCiAgcmVsb2NhdGUoQcOxbywgLmFmdGVyPURpYSkgJT4lDQogIHJlbG9jYXRlKE1lcywgLmFmdGVyPURpYSkNCg0KZGF0b3NfRXNwIDwtIGRhdG9zX0NDQUEgJT4lDQogIGZpbHRlcihjb2RfaW5lID09IDApICU+JQ0KICByZWxvY2F0ZShjb2RfaW5lLCAuYmVmb3JlPURpYSkgICNEYXRvcyBwYXJhIEVzcGHDsWEuDQoNCmRhdG9zX0NWIDwtIGRhdG9zX0NDQUEgJT4lDQogIGZpbHRlcihjb2RfaW5lID09IDEwKSAlPiUNCiAgcmVsb2NhdGUoY29kX2luZSwgLmJlZm9yZT1EaWEpICNEYXRvcyBwYXJhIGxhIENvbXVuaXRhdCBWYWxlbmNpYW5hLg0KDQpkYXRvc19Fc3BfU19OIDwtIGRhdG9zX0VzcCAlPiUgZmlsdGVyIChNZXMgPT0gIjA5InwgTWVzID09ICIxMCJ8IE1lcyA9PSAiMTEiKQ0KDQpkYXRvc19DVl9TX048LSBkYXRvc19DViAlPiUgZmlsdGVyIChNZXMgPT0gIjA5InwgTWVzID09ICIxMCJ8IE1lcyA9PSAiMTEiKQ0KDQpkYXRvc19Fc3BfTiA8LSBkYXRvc19Fc3AgJT4lIGZpbHRlcihNZXMgPT0gIjExIikNCmBgYA0KDQoqKkVWT0xVQ0nDk04gREUgTE9TIFBBQ0lFTlRFUyBJTkdSRVNBRE9TIFBPUiBDT1ZJRC0xOSoqDQpgYGB7cn0NCmdyYWZpY29fMSA8LSBnZ3Bsb3QoZGF0b3NfRXNwX1NfTiAsIGFlcyhEaWEgLCBgVG90YWwgUGFjaWVudGVzIENPVklEIGluZ3Jlc2Fkb3NgLCBncm91cD1NZXMsIGNvbG9yPSBNZXMpKSAgKyBnZW9tX2xpbmUoKSArIGxhYnModGl0bGUgPSAiIEV2b2x1Y2nDs24gZGUgcGFjaWVudGVzIGluZ3Jlc2Fkb3MgcG9yIGNvdmlkIGVuIEVzcGHDsWEiLCBzdWJ0aXRsZSA9ICJEZXNkZSBlbCAxIFNlcHRpZW1icmUgaGFzdGEgTm92aWVtYnJlIDMwIiwgY2FwdGlvbiA9ICJEYXRvcyByZXBvc2l0b3JpbyBDT1ZJRDE5IikNCmBgYA0KDQpgYGB7ciBvdXQud2lkdGg9IjcwJSIsIGVjaG89RkFMU0UsIGV2YWwgPSBUUlVFfQ0KZ3JhZmljb18xDQpgYGANCg0KDQpgYGB7cn0NCmdyYWZpY29fYSA8LSBnZ3Bsb3QoZGF0b3NfRXNwX04sIGFlcyhEaWEsIGBBbHRhcyBVbHQyNGhgLCAgIGZpbGwgPSBNZXMgKSkgKyAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZT0iU3BlY3RyYWwiKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSsgDQogIGxhYnModGl0bGUgPSAiTsO6bWVybyBkZSBwYWNpZW50ZXMgZGFkb3MgZGUgYWx0YSBwb3IgQ09WSUQgZW4gRXNwYcOxYSBhbCBkw61hIiwgc3VidGl0bGUgPSAiTWVzIE5vdmllbWJyZSIsIGNhcHRpb24gPSAiRWxhYm9yYWNpw7NuIHByb3BpYSBhIHBhcnRpciBkZSBkYXRvcyBDT1ZJRDE5IikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNCg0KZ3JhZmljb19hcCA8LSBncmFmaWNvX2EgKyANCiAgZ2VvbV90ZXh0KGFlcyh5PWBBbHRhcyBVbHQyNGhgLCANCiAgICBsYWJlbCA9IGBBbHRhcyBVbHQyNGhgKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOCksIA0KICAgIHNpemUgPSAzLjIsIHZqdXN0PTMsIGNvbCA9ICJCbGFjayIpDQpgYGANCg0KDQoNCmBgYHtyIG91dC53aWR0aD0iNzAlIiwgZWNobyA9IEZBTFNFLCBldmFsPSBUUlVFfQ0KZ3JhZmljb19hcA0KYGBgDQoNCmBgYHtyfQ0KI1ByZXBhcmFtb3MgbG9zIGRhdG9zIHBhcmEgaGFjZXIgdW5hIFRBQkxBDQpkYXRvc19DQ0FBX1NfTiA8LSBkYXRvc19DQ0FBICU+JSBmaWx0ZXIgKE1lcyA9PSAiMDkifCBNZXMgPT0gIjEwInwgTWVzID09ICIxMSIpDQoNCmRhdG9zX0NDQUFfeWFsdGFzIDwtIGRhdG9zX0NDQUFfU19OICU+JSBtdXRhdGUoYCVBbHRhcyBwb3IgaW5ncmVzYWRvc2AgID0gKGBBbHRhcyBVbHQyNGhgLyBgVG90YWwgUGFjaWVudGVzIENPVklEIGluZ3Jlc2Fkb3NgKSogMTAwKQ0KDQpkYXRvc19DQ0FBX3lhbHRhcyA8LSBkYXRvc19DQ0FBX3lhbHRhcyAlPiUgc2VsZWN0KERpYSwgTWVzLCBDQ0FBLCBgVG90YWwgUGFjaWVudGVzIENPVklEIGluZ3Jlc2Fkb3NgLCBgJSBDYW1hcyBPY3VwYWRhcyBDT1ZJRGAsIGBUb3RhbCBwYWNpZW50ZXMgQ09WSUQgZW4gVUNJYCwgYCVBbHRhcyBwb3IgaW5ncmVzYWRvc2ApDQpgYGANCg0KYGBge3IgZWNobyA9IEZBTFNFLCBldmFsID0gVFJVRX0NCkRUOjpkYXRhdGFibGUoZGF0b3NfQ0NBQV95YWx0YXMsIGZpbHRlciA9ICd0b3AnLA0KICAgICAgICAgICAgICBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gMTAgLCBhdXRvV2lkdGggPSBUUlVFICkpDQpgYGANCg0KIyMgNy4gQ29uY2x1c2nDs24NCg0KDQoNCg0KIyMgUmVmZXJlbmNpYXMNCg0KTGFzIHNpZ3VpZW50ZXMgcMOhZ2luYXMgd2ViIHNvbiBsYXMgcXVlIGhlbW9zIHV0aWxpemFkbyBwYXJhIGxhIHJlYWxpemFjacOzbiBkZWwgdHJhYmFqbzoNCg0KDQoNCi0tLS0tLS0tLS0tLS0tLS0NCg0KPGJyPg0KDQpQYXJhIGFjYWJhciBlc3RlIGNodW5rIGluY2x1aXLDqSBtaSBgc2Vzc2lvbiBpbmZvYDoNCg0KYGBge3J9DQpzZXNzaW9uaW5mbzo6c2Vzc2lvbl9pbmZvKCkgJT4lIGRldGFpbHM6OmRldGFpbHMoc3VtbWFyeSA9ICdjdXJyZW50IHNlc3Npb24gaW5mbycpIA0KYGBgDQoNClteMV06IFNpIHF1aWVyZXMgdmlzaXRhciBsYSB3ZWIgZGVsIGN1cnNvOiA8YSBocmVmPSJodHRwczovL3BlcmV6cDQ0LmdpdGh1Yi5pby9pbnRyby1kcy0yMC0yMS13ZWIvInRhcmdldD0iX2JsYW5rIj5odHRwczovL3BlcmV6cDQ0LmdpdGh1Yi5pby9pbnRyby1kcy0yMC0yMS13ZWIvPC9hPg0KDQpbXjJdOiBTaSBxdWllcmVzIGNvbnN1bHRhciBtw6FzIGluZm9ybWFjacOzbiBoYXogY2xpY2sgPGEgaHJlZj0iaHR0cHM6Ly93d3cubXNjYnMuZ29iLmVzL3Byb2Zlc2lvbmFsZXMvc2FsdWRQdWJsaWNhL2NjYXllcy9hbGVydGFzQWN0dWFsL25Db3YvZG9jdW1lbnRvcy9JVENvcm9uYXZpcnVzLnBkZiM6fjp0ZXh0PUVuJTIwZXN0ZSUyMG1vbWVudG8lMjBzZSUyMGRlc2Nvbm9jZSxvcmlnZW4lMjBkZSUyMGxhJTIwcGFuZGVtaWEuLyJ0YXJnZXQ9Il9ibGFuayI+IGFxdcOtPC9hPiANCg0KW14zXTogTm8gaGVtb3MgaGVjaG8gbGEgZXZvbHVjacOzbiBoYXN0YSBsYSBmZWNoYSBhY3R1YWwsIGRhZG8gcXVlIGEgcGFydGlyIGRlIGp1bGlvIGxvcyBkYXRvcyBkZSBjb250YWdpb3MgZW4gZmluZXMgZGUgc2VtYW5hIG11ZXN0cmFuIHVub3MgdmFsb3JlcyBkZSAwIChVbiByZXN1bHRhZG8gbm8gY29oZXJlbnRlKQ0K